diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 0f53f3d45..7c2bf6961 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -34,7 +34,7 @@ jobs: poetry install - name: Cache tox environments id: cache-tox - uses: actions/cache@v1 + uses: actions/cache@v2 with: path: .tox # setup.cfg, pyproject.toml, and .pre-commit-config.yaml have diff --git a/examples/colors.bas b/examples/colors.bas index 44726b0dd..a8182dc22 100644 --- a/examples/colors.bas +++ b/examples/colors.bas @@ -1,4 +1,5 @@ REM From the ZX Spectrum 48K Manual +CLS DIM m, n, c AS BYTE @@ -16,4 +17,3 @@ FOR c = 4 TO 7 INK c: PRINT c; " "; NEXT c: NEXT m PAPER 7: INK 0: BRIGHT 0 - diff --git a/examples/inputexample.bas b/examples/inputexample.bas index 977098bcf..2b6e7a779 100644 --- a/examples/inputexample.bas +++ b/examples/inputexample.bas @@ -1,7 +1,6 @@ #include - +border 1: cls print at 10, 5; "Type something: "; a$ = input(20) print print "You typed: "; a$ - diff --git a/src/arch/zx48k/library-asm/attr.asm b/src/arch/zx48k/library-asm/attr.asm index b083d1f11..7c228409b 100644 --- a/src/arch/zx48k/library-asm/attr.asm +++ b/src/arch/zx48k/library-asm/attr.asm @@ -4,8 +4,7 @@ #include once #include once #include once -#include once -#include once +#include once push namespace core @@ -14,6 +13,7 @@ __ATTR_ADDR: ; 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 @@ -21,13 +21,10 @@ __ATTR_ADDR: add hl, hl ; HL = A * 8 ; 15 T-States add hl, hl ; HL = A * 16 ; 15 T-States add hl, hl ; HL = A * 32 ; 15 T-States - - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address + ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address add hl, de - ; Return current screen address in HL ret @@ -41,12 +38,13 @@ SET_ATTR: 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 - call __ATTR_ADDR - __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 @@ -64,20 +62,4 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address ENDP - -; Sets the attribute at a given screen pixel address in hl -; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace diff --git a/src/arch/zx48k/library-asm/bright.asm b/src/arch/zx48k/library-asm/bright.asm index c4a7b58ed..13feb8fd4 100644 --- a/src/arch/zx48k/library-asm/bright.asm +++ b/src/arch/zx48k/library-asm/bright.asm @@ -1,7 +1,7 @@ ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register -#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/cls.asm b/src/arch/zx48k/library-asm/cls.asm index 437d47988..21aab73c8 100644 --- a/src/arch/zx48k/library-asm/cls.asm +++ b/src/arch/zx48k/library-asm/cls.asm @@ -1,51 +1,38 @@ -; JUMPS directly to spectrum CLS -; This routine does not clear lower screen +;; Clears the user screen (24 rows) -;CLS EQU 0DAFh - -; Our faster implementation - -#include once +#include once push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret -COORDS EQU 23677 -SCREEN EQU 16384 ; Default start of the screen (can be changed) -ATTR_P EQU 23693 -;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - -SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace - diff --git a/src/arch/zx48k/library-asm/const.asm b/src/arch/zx48k/library-asm/const.asm deleted file mode 100644 index 95a99b513..000000000 --- a/src/arch/zx48k/library-asm/const.asm +++ /dev/null @@ -1,14 +0,0 @@ -; Global constants - - push namespace core - -P_FLAG EQU 23697 -FLAGS2 EQU 23681 -ATTR_P EQU 23693 ; permanet ATTRIBUTES -ATTR_T EQU 23695 ; temporary ATTRIBUTES -CHARS EQU 23606 ; Pointer to ROM/RAM Charset -UDG EQU 23675 ; Pointer to UDG Charset -MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - - pop namespace - diff --git a/src/arch/zx48k/library-asm/copy_attr.asm b/src/arch/zx48k/library-asm/copy_attr.asm index c21c3d852..15015ec18 100644 --- a/src/arch/zx48k/library-asm/copy_attr.asm +++ b/src/arch/zx48k/library-asm/copy_attr.asm @@ -2,7 +2,7 @@ #include once #endif -#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/draw.asm b/src/arch/zx48k/library-asm/draw.asm index 2037d18a0..ea886171d 100644 --- a/src/arch/zx48k/library-asm/draw.asm +++ b/src/arch/zx48k/library-asm/draw.asm @@ -8,8 +8,8 @@ #include once #include once -#include once -#include once +#include once +#include once #include once #include once @@ -330,4 +330,3 @@ __FASTPLOTEND: ENDP pop namespace - diff --git a/src/arch/zx48k/library-asm/flash.asm b/src/arch/zx48k/library-asm/flash.asm index 507ab4980..2ba5a7e53 100644 --- a/src/arch/zx48k/library-asm/flash.asm +++ b/src/arch/zx48k/library-asm/flash.asm @@ -1,7 +1,7 @@ ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register -#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/in_screen.asm b/src/arch/zx48k/library-asm/in_screen.asm index 23eb2a222..724450c7a 100644 --- a/src/arch/zx48k/library-asm/in_screen.asm +++ b/src/arch/zx48k/library-asm/in_screen.asm @@ -5,21 +5,18 @@ __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: diff --git a/src/arch/zx48k/library-asm/ink.asm b/src/arch/zx48k/library-asm/ink.asm index 89763d0ca..7dcb64113 100644 --- a/src/arch/zx48k/library-asm/ink.asm +++ b/src/arch/zx48k/library-asm/ink.asm @@ -1,7 +1,7 @@ ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/over.asm b/src/arch/zx48k/library-asm/over.asm index ab9d671b1..afe15fc55 100644 --- a/src/arch/zx48k/library-asm/over.asm +++ b/src/arch/zx48k/library-asm/over.asm @@ -1,7 +1,7 @@ ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #include once -#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/paper.asm b/src/arch/zx48k/library-asm/paper.asm index f6ab7dd19..55c9600ba 100644 --- a/src/arch/zx48k/library-asm/paper.asm +++ b/src/arch/zx48k/library-asm/paper.asm @@ -1,7 +1,7 @@ ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register -#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/plot.asm b/src/arch/zx48k/library-asm/plot.asm index 1c44482f1..869e85e80 100644 --- a/src/arch/zx48k/library-asm/plot.asm +++ b/src/arch/zx48k/library-asm/plot.asm @@ -6,8 +6,8 @@ #include once #include once -#include once -#include once +#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/print.asm b/src/arch/zx48k/library-asm/print.asm index cbb048bc8..a238afa1e 100644 --- a/src/arch/zx48k/library-asm/print.asm +++ b/src/arch/zx48k/library-asm/print.asm @@ -1,10 +1,8 @@ ; vim:ts=4:sw=4:et: -; vim:ts=4:sw=4:et: ; PRINT command routine ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #include once -#include once #include once #include once #include once @@ -15,7 +13,7 @@ #include once #include once #include once -#include once +#include once #include once ; Putting a comment starting with @INIT
@@ -31,14 +29,21 @@ __PRINT_INIT: ; To be called before program starts (initializes library) ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - - xor a - ld (FLAGS2), a - - ret + 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 @@ -46,77 +51,55 @@ __PRINTCHAR: ; Print character store in accumulator (A register) LOCAL PO_GR_1 LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch -PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 +PRINT_JUMP_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 -#ifndef DISABLE_SCROLL - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#endif - __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - -#ifndef DISABLE_SCROLL - call __SCROLL +__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 + +#ifndef __ZXB_DISABLE_SCROLL + inc h + push hl + call __SCROLL_SCR + pop hl +#else + ld h, SCR_ROWS - 1 #endif - call __LOAD_S_POSN - -; At this point we have the new coord - ld hl, (SCREEN_ADDR) - - ld a, d - ld c, a ; Saves it for later - - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR + cp 80h ; Is it a "normal" (printable) char + jr c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG + cp 90h ; Is it an UDG? + jr nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + ; 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 @@ -128,7 +111,7 @@ PO_GR_1 EQU 0B38h __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: @@ -144,28 +127,39 @@ __PRGRAPH0: __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address + +#ifndef __ZXB_DISABLE_BOLD bit 2, (iy + $47) call nz, __BOLD +#endif + +#ifndef __ZXB_DISABLE_ITALIC bit 4, (iy + $47) call nz, __ITALIC +#endif + + ld hl, (DFCC) + push hl + ld b, 8 ; 8 bytes per char + __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a @@ -173,65 +167,47 @@ INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 - -__PRINT_CONT: - call __SAVE_S_POSN + pop hl + inc hl + ld (DFCC), hl -__PRINT_CONT2: + ld hl, (DFCCL) ; current ATTR Pos + push hl + call __SET_ATTR + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A - PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) -#ifndef DISABLE_SCROLL - call __SCROLL -#endif - call __LOAD_S_POSN - -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 - -__PRINT_EOL2: - ld a, d - inc a - -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d -#ifndef DISABLE_SCROLL - ld hl, __TVFLAGS - set 1, (hl) - dec a + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f +#ifndef __ZXB_DISABLE_SCROLL + inc h + push hl + call __SCROLL_SCR + pop hl #else - xor a + ld h, SCR_ROWS - 1 #endif +1: + ld l, 1 __PRINT_EOL_END: - ld d, a - -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret @@ -269,13 +245,13 @@ __PRINT_TAB2: pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE + __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE - -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call @@ -283,118 +259,115 @@ __PRINT_SET_STATE: ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a + ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART +#ifndef __ZXB_DISABLE_BOLD __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#endif +#ifndef __ZXB_DISABLE_ITALIC __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#endif +#ifndef __ZXB_DISABLE_BOLD + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -402,11 +375,14 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#endif +#ifndef __ZXB_DISABLE_ITALIC + LOCAL __ITALIC __ITALIC: push hl @@ -431,6 +407,85 @@ __ITALIC: pop hl ld de, MEM0 ret +#endif + +#ifndef __ZXB_DISABLE_SCROLL + LOCAL __SCROLL_SCR + +# ifdef __ZXB_ENABLE_BUFFER_SCROLL +__SCROLL_SCR: ;; Scrolls screen and attrs 1 row up + ld de, (SCREEN_ADDR) + ld b, 3 +3: + push bc + ld a, 8 +1: + ld hl, 32 + add hl, de + ld bc, 32 * 7 + push de + ldir + pop de + inc d + dec a + jr nz, 1b + push hl + ld bc, -32 - 256 * 7 + add hl, bc + ex de, hl + ld a, 8 +2: + ld bc, 32 + push hl + push de + ldir + pop de + pop hl + inc d + inc h + dec a + jr nz, 2b + pop de + pop bc + djnz 3b + + dec de + ld h, d + ld l, e + ld a, 8 +3: + push hl + push de + ld (hl), b + dec de + ld bc, 31 + lddr + pop de + pop hl + dec d + dec h + dec a + jr nz, 3b + + ld de, (SCREEN_ATTR_ADDR) + ld hl, 32 + add hl, de + ld bc, 32 * 23 + ldir + + ld h, d + ld l, e + ld a, (ATTR_P) + ld (hl), a + inc de + ld bc, 31 + ldir + ret +# else +__SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +# endif +#endif + PRINT_COMMA: call __LOAD_S_POSN @@ -440,21 +495,13 @@ PRINT_COMMA: PRINT_TAB: PROC - LOCAL LOOP, CONTINUE + LOCAL LOOP - inc a call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z + ld b, a LOOP: ld a, ' ' @@ -478,31 +525,31 @@ PRINT_AT: ; Changes cursor to ROW, COL call __IN_SCREEN ret nc ; Return if out of screen -#ifndef DISABLE_SCROLL - ld hl, __TVFLAGS - res 1, (hl) -#endif jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 +#ifndef __ZXB_DISABLE_ITALIC + LOCAL __PRINT_ITA2 +#else + __PRINT_ITA EQU __PRINT_NOP +#endif + +#ifndef __ZXB_DISABLE_BOLD + LOCAL __PRINT_BOLD2 +#else + __PRINT_BOLD EQU __PRINT_NOP +#endif + __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 @@ -533,5 +580,3 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ENDP pop namespace - - diff --git a/src/arch/zx48k/library-asm/printf.asm b/src/arch/zx48k/library-asm/printf.asm index 917130b62..73c713f09 100644 --- a/src/arch/zx48k/library-asm/printf.asm +++ b/src/arch/zx48k/library-asm/printf.asm @@ -1,6 +1,6 @@ #include once #include once -#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/printnum.asm b/src/arch/zx48k/library-asm/printnum.asm index 8e0c21f63..28e4e98fe 100644 --- a/src/arch/zx48k/library-asm/printnum.asm +++ b/src/arch/zx48k/library-asm/printnum.asm @@ -27,12 +27,10 @@ __PRINTU_CONT: ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 - - diff --git a/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm b/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm new file mode 100644 index 000000000..0e95a4f94 --- /dev/null +++ b/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm @@ -0,0 +1,20 @@ +#include once + +push namespace core + +; Sets the attribute at a given screen pixel address in hl +; HL contains the address in RAM for a given pixel (not a coordinate) +SET_PIXEL_ADDR_ATTR: + ;; gets ATTR position with offset given in SCREEN_ADDR + ld a, h + rrca + rrca + rrca + and 3 + + ld h, a + ld de, (SCREEN_ATTR_ADDR) + add hl, de ;; Final screen addr + jp __SET_ATTR2 + +pop namespace diff --git a/src/arch/zx48k/library-asm/sposn.asm b/src/arch/zx48k/library-asm/sposn.asm index 4c8a62d2c..223d8dd89 100644 --- a/src/arch/zx48k/library-asm/sposn.asm +++ b/src/arch/zx48k/library-asm/sposn.asm @@ -1,35 +1,58 @@ +#include once +#include once + ; Printing positioning library. push namespace core +; Loads into DE current ROW, COL print position from S_POSN mem var. +__LOAD_S_POSN: PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. ld de, (S_POSN) - ld hl, (MAXX) + ld hl, SCR_SIZE or a sbc hl, de ex de, hl ret + ENDP + -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) +; 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 - ret +__SET_SCR_PTR: ;; Fast + push de + call __ATTR_ADDR + ld (DFCCL), hl + pop de -ECHO_E EQU 23682 -MAXX EQU ECHO_E ; Max X position + 1 -MAXY EQU MAXX + 1 ; Max Y position + 1 + ld a, d + ld c, a ; Saves it for later -S_POSN EQU 23688 -POSX EQU S_POSN ; Current POS X -POSY EQU S_POSN + 1 ; Current POS Y + 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 - diff --git a/src/arch/zx48k/library-asm/str.asm b/src/arch/zx48k/library-asm/str.asm index 49f63d2a9..1e5e306b5 100644 --- a/src/arch/zx48k/library-asm/str.asm +++ b/src/arch/zx48k/library-asm/str.asm @@ -6,7 +6,7 @@ #include once #include once -#include once +#include once push namespace core diff --git a/src/arch/zx48k/library-asm/sysvars.asm b/src/arch/zx48k/library-asm/sysvars.asm new file mode 100644 index 000000000..14bd87396 --- /dev/null +++ b/src/arch/zx48k/library-asm/sysvars.asm @@ -0,0 +1,30 @@ +;; ----------------------------------------------------------------------- +;; 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 +TVFLAGS EQU 23612 ; TV Flags +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 diff --git a/src/arch/zx48k/library-asm/usr_str.asm b/src/arch/zx48k/library-asm/usr_str.asm index a6f6035c6..a2b047b9e 100644 --- a/src/arch/zx48k/library-asm/usr_str.asm +++ b/src/arch/zx48k/library-asm/usr_str.asm @@ -6,7 +6,7 @@ ; and A register is non-zero if the string must be freed (TMP string) #include once -#include once +#include once #include once push namespace core diff --git a/src/arch/zxnext/library-asm/attr.asm b/src/arch/zxnext/library-asm/attr.asm index b083d1f11..7c228409b 100644 --- a/src/arch/zxnext/library-asm/attr.asm +++ b/src/arch/zxnext/library-asm/attr.asm @@ -4,8 +4,7 @@ #include once #include once #include once -#include once -#include once +#include once push namespace core @@ -14,6 +13,7 @@ __ATTR_ADDR: ; 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 @@ -21,13 +21,10 @@ __ATTR_ADDR: add hl, hl ; HL = A * 8 ; 15 T-States add hl, hl ; HL = A * 16 ; 15 T-States add hl, hl ; HL = A * 32 ; 15 T-States - - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address + ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address add hl, de - ; Return current screen address in HL ret @@ -41,12 +38,13 @@ SET_ATTR: 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 - call __ATTR_ADDR - __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 @@ -64,20 +62,4 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address ENDP - -; Sets the attribute at a given screen pixel address in hl -; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace diff --git a/src/arch/zxnext/library-asm/bright.asm b/src/arch/zxnext/library-asm/bright.asm index c4a7b58ed..13feb8fd4 100644 --- a/src/arch/zxnext/library-asm/bright.asm +++ b/src/arch/zxnext/library-asm/bright.asm @@ -1,7 +1,7 @@ ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register -#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/cls.asm b/src/arch/zxnext/library-asm/cls.asm index 437d47988..7f9e773ec 100644 --- a/src/arch/zxnext/library-asm/cls.asm +++ b/src/arch/zxnext/library-asm/cls.asm @@ -1,51 +1,39 @@ -; JUMPS directly to spectrum CLS -; This routine does not clear lower screen - -;CLS EQU 0DAFh - -; Our faster implementation +;; Clears the user screen (24 rows) #include once +#include once push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret -COORDS EQU 23677 -SCREEN EQU 16384 ; Default start of the screen (can be changed) -ATTR_P EQU 23693 -;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - -SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace - diff --git a/src/arch/zxnext/library-asm/const.asm b/src/arch/zxnext/library-asm/const.asm deleted file mode 100644 index 95a99b513..000000000 --- a/src/arch/zxnext/library-asm/const.asm +++ /dev/null @@ -1,14 +0,0 @@ -; Global constants - - push namespace core - -P_FLAG EQU 23697 -FLAGS2 EQU 23681 -ATTR_P EQU 23693 ; permanet ATTRIBUTES -ATTR_T EQU 23695 ; temporary ATTRIBUTES -CHARS EQU 23606 ; Pointer to ROM/RAM Charset -UDG EQU 23675 ; Pointer to UDG Charset -MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - - pop namespace - diff --git a/src/arch/zxnext/library-asm/copy_attr.asm b/src/arch/zxnext/library-asm/copy_attr.asm index c21c3d852..15015ec18 100644 --- a/src/arch/zxnext/library-asm/copy_attr.asm +++ b/src/arch/zxnext/library-asm/copy_attr.asm @@ -2,7 +2,7 @@ #include once #endif -#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/draw.asm b/src/arch/zxnext/library-asm/draw.asm index 2037d18a0..ea886171d 100644 --- a/src/arch/zxnext/library-asm/draw.asm +++ b/src/arch/zxnext/library-asm/draw.asm @@ -8,8 +8,8 @@ #include once #include once -#include once -#include once +#include once +#include once #include once #include once @@ -330,4 +330,3 @@ __FASTPLOTEND: ENDP pop namespace - diff --git a/src/arch/zxnext/library-asm/flash.asm b/src/arch/zxnext/library-asm/flash.asm index 507ab4980..2ba5a7e53 100644 --- a/src/arch/zxnext/library-asm/flash.asm +++ b/src/arch/zxnext/library-asm/flash.asm @@ -1,7 +1,7 @@ ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register -#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/in_screen.asm b/src/arch/zxnext/library-asm/in_screen.asm index 23eb2a222..724450c7a 100644 --- a/src/arch/zxnext/library-asm/in_screen.asm +++ b/src/arch/zxnext/library-asm/in_screen.asm @@ -5,21 +5,18 @@ __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: diff --git a/src/arch/zxnext/library-asm/ink.asm b/src/arch/zxnext/library-asm/ink.asm index 89763d0ca..7dcb64113 100644 --- a/src/arch/zxnext/library-asm/ink.asm +++ b/src/arch/zxnext/library-asm/ink.asm @@ -1,7 +1,7 @@ ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/over.asm b/src/arch/zxnext/library-asm/over.asm index ab9d671b1..afe15fc55 100644 --- a/src/arch/zxnext/library-asm/over.asm +++ b/src/arch/zxnext/library-asm/over.asm @@ -1,7 +1,7 @@ ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #include once -#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/paper.asm b/src/arch/zxnext/library-asm/paper.asm index f6ab7dd19..55c9600ba 100644 --- a/src/arch/zxnext/library-asm/paper.asm +++ b/src/arch/zxnext/library-asm/paper.asm @@ -1,7 +1,7 @@ ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register -#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/plot.asm b/src/arch/zxnext/library-asm/plot.asm index 1c44482f1..869e85e80 100644 --- a/src/arch/zxnext/library-asm/plot.asm +++ b/src/arch/zxnext/library-asm/plot.asm @@ -6,8 +6,8 @@ #include once #include once -#include once -#include once +#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/print.asm b/src/arch/zxnext/library-asm/print.asm index cbb048bc8..a238afa1e 100644 --- a/src/arch/zxnext/library-asm/print.asm +++ b/src/arch/zxnext/library-asm/print.asm @@ -1,10 +1,8 @@ ; vim:ts=4:sw=4:et: -; vim:ts=4:sw=4:et: ; PRINT command routine ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #include once -#include once #include once #include once #include once @@ -15,7 +13,7 @@ #include once #include once #include once -#include once +#include once #include once ; Putting a comment starting with @INIT
@@ -31,14 +29,21 @@ __PRINT_INIT: ; To be called before program starts (initializes library) ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - - xor a - ld (FLAGS2), a - - ret + 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 @@ -46,77 +51,55 @@ __PRINTCHAR: ; Print character store in accumulator (A register) LOCAL PO_GR_1 LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch -PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 +PRINT_JUMP_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 -#ifndef DISABLE_SCROLL - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#endif - __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - -#ifndef DISABLE_SCROLL - call __SCROLL +__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 + +#ifndef __ZXB_DISABLE_SCROLL + inc h + push hl + call __SCROLL_SCR + pop hl +#else + ld h, SCR_ROWS - 1 #endif - call __LOAD_S_POSN - -; At this point we have the new coord - ld hl, (SCREEN_ADDR) - - ld a, d - ld c, a ; Saves it for later - - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR + cp 80h ; Is it a "normal" (printable) char + jr c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG + cp 90h ; Is it an UDG? + jr nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + ; 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 @@ -128,7 +111,7 @@ PO_GR_1 EQU 0B38h __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: @@ -144,28 +127,39 @@ __PRGRAPH0: __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address + +#ifndef __ZXB_DISABLE_BOLD bit 2, (iy + $47) call nz, __BOLD +#endif + +#ifndef __ZXB_DISABLE_ITALIC bit 4, (iy + $47) call nz, __ITALIC +#endif + + ld hl, (DFCC) + push hl + ld b, 8 ; 8 bytes per char + __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a @@ -173,65 +167,47 @@ INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 - -__PRINT_CONT: - call __SAVE_S_POSN + pop hl + inc hl + ld (DFCC), hl -__PRINT_CONT2: + ld hl, (DFCCL) ; current ATTR Pos + push hl + call __SET_ATTR + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A - PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) -#ifndef DISABLE_SCROLL - call __SCROLL -#endif - call __LOAD_S_POSN - -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 - -__PRINT_EOL2: - ld a, d - inc a - -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d -#ifndef DISABLE_SCROLL - ld hl, __TVFLAGS - set 1, (hl) - dec a + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f +#ifndef __ZXB_DISABLE_SCROLL + inc h + push hl + call __SCROLL_SCR + pop hl #else - xor a + ld h, SCR_ROWS - 1 #endif +1: + ld l, 1 __PRINT_EOL_END: - ld d, a - -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret @@ -269,13 +245,13 @@ __PRINT_TAB2: pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE + __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE - -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call @@ -283,118 +259,115 @@ __PRINT_SET_STATE: ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a + ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART +#ifndef __ZXB_DISABLE_BOLD __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#endif +#ifndef __ZXB_DISABLE_ITALIC __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#endif +#ifndef __ZXB_DISABLE_BOLD + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -402,11 +375,14 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#endif +#ifndef __ZXB_DISABLE_ITALIC + LOCAL __ITALIC __ITALIC: push hl @@ -431,6 +407,85 @@ __ITALIC: pop hl ld de, MEM0 ret +#endif + +#ifndef __ZXB_DISABLE_SCROLL + LOCAL __SCROLL_SCR + +# ifdef __ZXB_ENABLE_BUFFER_SCROLL +__SCROLL_SCR: ;; Scrolls screen and attrs 1 row up + ld de, (SCREEN_ADDR) + ld b, 3 +3: + push bc + ld a, 8 +1: + ld hl, 32 + add hl, de + ld bc, 32 * 7 + push de + ldir + pop de + inc d + dec a + jr nz, 1b + push hl + ld bc, -32 - 256 * 7 + add hl, bc + ex de, hl + ld a, 8 +2: + ld bc, 32 + push hl + push de + ldir + pop de + pop hl + inc d + inc h + dec a + jr nz, 2b + pop de + pop bc + djnz 3b + + dec de + ld h, d + ld l, e + ld a, 8 +3: + push hl + push de + ld (hl), b + dec de + ld bc, 31 + lddr + pop de + pop hl + dec d + dec h + dec a + jr nz, 3b + + ld de, (SCREEN_ATTR_ADDR) + ld hl, 32 + add hl, de + ld bc, 32 * 23 + ldir + + ld h, d + ld l, e + ld a, (ATTR_P) + ld (hl), a + inc de + ld bc, 31 + ldir + ret +# else +__SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +# endif +#endif + PRINT_COMMA: call __LOAD_S_POSN @@ -440,21 +495,13 @@ PRINT_COMMA: PRINT_TAB: PROC - LOCAL LOOP, CONTINUE + LOCAL LOOP - inc a call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z + ld b, a LOOP: ld a, ' ' @@ -478,31 +525,31 @@ PRINT_AT: ; Changes cursor to ROW, COL call __IN_SCREEN ret nc ; Return if out of screen -#ifndef DISABLE_SCROLL - ld hl, __TVFLAGS - res 1, (hl) -#endif jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 +#ifndef __ZXB_DISABLE_ITALIC + LOCAL __PRINT_ITA2 +#else + __PRINT_ITA EQU __PRINT_NOP +#endif + +#ifndef __ZXB_DISABLE_BOLD + LOCAL __PRINT_BOLD2 +#else + __PRINT_BOLD EQU __PRINT_NOP +#endif + __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 @@ -533,5 +580,3 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ENDP pop namespace - - diff --git a/src/arch/zxnext/library-asm/printf.asm b/src/arch/zxnext/library-asm/printf.asm index 917130b62..73c713f09 100644 --- a/src/arch/zxnext/library-asm/printf.asm +++ b/src/arch/zxnext/library-asm/printf.asm @@ -1,6 +1,6 @@ #include once #include once -#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/printnum.asm b/src/arch/zxnext/library-asm/printnum.asm index 8e0c21f63..28e4e98fe 100644 --- a/src/arch/zxnext/library-asm/printnum.asm +++ b/src/arch/zxnext/library-asm/printnum.asm @@ -27,12 +27,10 @@ __PRINTU_CONT: ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 - - diff --git a/src/arch/zxnext/library-asm/set_pixel_addr_attr.asm b/src/arch/zxnext/library-asm/set_pixel_addr_attr.asm new file mode 100644 index 000000000..0e95a4f94 --- /dev/null +++ b/src/arch/zxnext/library-asm/set_pixel_addr_attr.asm @@ -0,0 +1,20 @@ +#include once + +push namespace core + +; Sets the attribute at a given screen pixel address in hl +; HL contains the address in RAM for a given pixel (not a coordinate) +SET_PIXEL_ADDR_ATTR: + ;; gets ATTR position with offset given in SCREEN_ADDR + ld a, h + rrca + rrca + rrca + and 3 + + ld h, a + ld de, (SCREEN_ATTR_ADDR) + add hl, de ;; Final screen addr + jp __SET_ATTR2 + +pop namespace diff --git a/src/arch/zxnext/library-asm/sposn.asm b/src/arch/zxnext/library-asm/sposn.asm index 4c8a62d2c..223d8dd89 100644 --- a/src/arch/zxnext/library-asm/sposn.asm +++ b/src/arch/zxnext/library-asm/sposn.asm @@ -1,35 +1,58 @@ +#include once +#include once + ; Printing positioning library. push namespace core +; Loads into DE current ROW, COL print position from S_POSN mem var. +__LOAD_S_POSN: PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. ld de, (S_POSN) - ld hl, (MAXX) + ld hl, SCR_SIZE or a sbc hl, de ex de, hl ret + ENDP + -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) +; 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 - ret +__SET_SCR_PTR: ;; Fast + push de + call __ATTR_ADDR + ld (DFCCL), hl + pop de -ECHO_E EQU 23682 -MAXX EQU ECHO_E ; Max X position + 1 -MAXY EQU MAXX + 1 ; Max Y position + 1 + ld a, d + ld c, a ; Saves it for later -S_POSN EQU 23688 -POSX EQU S_POSN ; Current POS X -POSY EQU S_POSN + 1 ; Current POS Y + 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 - diff --git a/src/arch/zxnext/library-asm/str.asm b/src/arch/zxnext/library-asm/str.asm index 49f63d2a9..1e5e306b5 100644 --- a/src/arch/zxnext/library-asm/str.asm +++ b/src/arch/zxnext/library-asm/str.asm @@ -6,7 +6,7 @@ #include once #include once -#include once +#include once push namespace core diff --git a/src/arch/zxnext/library-asm/sysvars.asm b/src/arch/zxnext/library-asm/sysvars.asm new file mode 100644 index 000000000..14bd87396 --- /dev/null +++ b/src/arch/zxnext/library-asm/sysvars.asm @@ -0,0 +1,30 @@ +;; ----------------------------------------------------------------------- +;; 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 +TVFLAGS EQU 23612 ; TV Flags +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 diff --git a/src/arch/zxnext/library-asm/usr_str.asm b/src/arch/zxnext/library-asm/usr_str.asm index a6f6035c6..a2b047b9e 100644 --- a/src/arch/zxnext/library-asm/usr_str.asm +++ b/src/arch/zxnext/library-asm/usr_str.asm @@ -6,7 +6,7 @@ ; and A register is non-zero if the string must be freed (TMP string) #include once -#include once +#include once #include once push namespace core diff --git a/tests/functional/zx48k/astore16.asm b/tests/functional/zx48k/astore16.asm index 84323ea5c..dd61fc658 100644 --- a/tests/functional/zx48k/astore16.asm +++ b/tests/functional/zx48k/astore16.asm @@ -244,79 +244,42 @@ TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables ENDP pop namespace -#line 51 "astore16.bas" +#line 51 "zx48k/astore16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -351,22 +314,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -375,7 +336,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -392,22 +439,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -441,7 +476,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -481,7 +516,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -518,7 +553,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -555,7 +590,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -648,7 +683,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -676,7 +711,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -704,7 +739,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -734,67 +769,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -803,68 +778,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -873,7 +841,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -888,71 +856,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -985,109 +946,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1095,10 +1049,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1122,6 +1078,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1129,20 +1091,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1163,28 +1116,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1212,7 +1158,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 52 "astore16.bas" +#line 52 "zx48k/astore16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1233,7 +1179,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1360,5 +1306,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 53 "astore16.bas" +#line 53 "zx48k/astore16.bas" END diff --git a/tests/functional/zx48k/attr.asm b/tests/functional/zx48k/attr.asm index 26ce0f94a..94d48caf4 100644 --- a/tests/functional/zx48k/attr.asm +++ b/tests/functional/zx48k/attr.asm @@ -51,17 +51,32 @@ ; Parameter: BOLD flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" push namespace core COPY_ATTR: @@ -116,7 +131,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 28 "attr.bas" +#line 28 "zx48k/attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -153,7 +168,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 30 "attr.bas" +#line 30 "zx48k/attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register @@ -190,7 +205,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 31 "attr.bas" +#line 31 "zx48k/attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -229,7 +244,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 32 "attr.bas" +#line 32 "zx48k/attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -269,5 +284,5 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 33 "attr.bas" +#line 33 "zx48k/attr.bas" END diff --git a/tests/functional/zx48k/attr_in_subs.asm b/tests/functional/zx48k/attr_in_subs.asm index dcfdc61d0..f62cb71b4 100644 --- a/tests/functional/zx48k/attr_in_subs.asm +++ b/tests/functional/zx48k/attr_in_subs.asm @@ -55,17 +55,32 @@ _screenAttributes2__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 5 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" push namespace core BRIGHT: @@ -100,73 +115,38 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 34 "attr_in_subs.bas" +#line 34 "zx48k/attr_in_subs.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation -#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + ;; Clears the user screen (24 rows) push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace -#line 35 "attr_in_subs.bas" +#line 35 "zx48k/attr_in_subs.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" push namespace core @@ -197,7 +177,7 @@ __REFRESH_TMP: ret ENDP pop namespace -#line 36 "attr_in_subs.bas" +#line 36 "zx48k/attr_in_subs.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register @@ -234,7 +214,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 37 "attr_in_subs.bas" +#line 37 "zx48k/attr_in_subs.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -274,5 +254,5 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 38 "attr_in_subs.bas" +#line 38 "zx48k/attr_in_subs.bas" END diff --git a/tests/functional/zx48k/circle.asm b/tests/functional/zx48k/circle.asm index 92ac9c608..989a0dc74 100644 --- a/tests/functional/zx48k/circle.asm +++ b/tests/functional/zx48k/circle.asm @@ -144,125 +144,51 @@ __STOP: ; X in top of the stack #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" - push namespace core -__IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret - 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address + ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address add hl, de ; Return current screen address in HL ret @@ -273,10 +199,11 @@ 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 - call __ATTR_ADDR __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 @@ -289,6 +216,73 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address ld (hl), a ; Store result in screen ret ENDP + pop namespace +#line 3 "/zxbasic/src/arch/zx48k/library-asm/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 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core +__IN_SCREEN: + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits + 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm" + push namespace core ; Sets the attribute at a given screen pixel address in hl ; HL contains the address in RAM for a given pixel (not a coordinate) SET_PIXEL_ADDR_ATTR: @@ -298,12 +292,11 @@ SET_PIXEL_ADDR_ATTR: rrca rrca and 3 - or 18h ld h, a - ld de, (SCREEN_ADDR) + ld de, (SCREEN_ATTR_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 - pop namespace + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" push namespace core PLOT: @@ -529,7 +522,7 @@ __CIRCLE_PLOT: ret ENDP pop namespace -#line 75 "circle.bas" +#line 75 "zx48k/circle.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -628,5 +621,5 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 76 "circle.bas" +#line 76 "zx48k/circle.bas" END diff --git a/tests/functional/zx48k/code00.asm b/tests/functional/zx48k/code00.asm index c3288314f..d410dd598 100644 --- a/tests/functional/zx48k/code00.asm +++ b/tests/functional/zx48k/code00.asm @@ -322,77 +322,40 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -427,22 +390,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -451,7 +412,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -468,22 +515,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -517,7 +552,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -557,7 +592,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -594,7 +629,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -631,7 +666,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -701,7 +736,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -729,7 +764,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -757,7 +792,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -787,67 +822,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -856,68 +831,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -926,7 +894,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -941,71 +909,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1038,109 +999,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1148,10 +1102,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1175,6 +1131,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1182,20 +1144,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1216,28 +1169,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1522,7 +1468,7 @@ PRINT_TAPE_MSG: ENDP #line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" pop namespace -#line 29 "code00.bas" +#line 29 "zx48k/code00.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -1718,5 +1664,5 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 30 "code00.bas" +#line 30 "zx48k/code00.bas" END diff --git a/tests/functional/zx48k/code01.asm b/tests/functional/zx48k/code01.asm index c22459e8e..5a49c6fe1 100644 --- a/tests/functional/zx48k/code01.asm +++ b/tests/functional/zx48k/code01.asm @@ -322,77 +322,40 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -427,22 +390,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -451,7 +412,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -468,22 +515,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -517,7 +552,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -557,7 +592,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -594,7 +629,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -631,7 +666,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -701,7 +736,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -729,7 +764,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -757,7 +792,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -787,67 +822,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -856,68 +831,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -926,7 +894,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -941,71 +909,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1038,109 +999,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1148,10 +1102,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1175,6 +1131,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1182,20 +1144,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1216,28 +1169,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1522,7 +1468,7 @@ PRINT_TAPE_MSG: ENDP #line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" pop namespace -#line 29 "code01.bas" +#line 29 "zx48k/code01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -1718,5 +1664,5 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 30 "code01.bas" +#line 30 "zx48k/code01.bas" END diff --git a/tests/functional/zx48k/code02.asm b/tests/functional/zx48k/code02.asm index bf27c5a87..80a954fab 100644 --- a/tests/functional/zx48k/code02.asm +++ b/tests/functional/zx48k/code02.asm @@ -322,77 +322,40 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -427,22 +390,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -451,7 +412,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -468,22 +515,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -517,7 +552,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -557,7 +592,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -594,7 +629,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -631,7 +666,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -701,7 +736,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -729,7 +764,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -757,7 +792,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -787,67 +822,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -856,68 +831,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -926,7 +894,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -941,71 +909,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1038,109 +999,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1148,10 +1102,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1175,6 +1131,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1182,20 +1144,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1216,28 +1169,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1522,7 +1468,7 @@ PRINT_TAPE_MSG: ENDP #line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" pop namespace -#line 29 "code02.bas" +#line 29 "zx48k/code02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -1718,5 +1664,5 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 30 "code02.bas" +#line 30 "zx48k/code02.bas" END diff --git a/tests/functional/zx48k/coercion3.asm b/tests/functional/zx48k/coercion3.asm index 42bc67ad8..fd722061e 100644 --- a/tests/functional/zx48k/coercion3.asm +++ b/tests/functional/zx48k/coercion3.asm @@ -50,17 +50,32 @@ _c: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" push namespace core COPY_ATTR: @@ -90,7 +105,7 @@ __REFRESH_TMP: ret ENDP pop namespace -#line 28 "coercion3.bas" +#line 28 "zx48k/coercion3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -130,5 +145,5 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 29 "coercion3.bas" +#line 29 "zx48k/coercion3.bas" END diff --git a/tests/functional/zx48k/draw.asm b/tests/functional/zx48k/draw.asm index ed4753930..fbb11ee81 100644 --- a/tests/functional/zx48k/draw.asm +++ b/tests/functional/zx48k/draw.asm @@ -110,125 +110,51 @@ __STOP: #line 9 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" - push namespace core -__IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret - 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 10 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address + ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address add hl, de ; Return current screen address in HL ret @@ -239,10 +165,11 @@ 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 - call __ATTR_ADDR __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 @@ -255,6 +182,73 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address ld (hl), a ; Store result in screen ret ENDP + pop namespace +#line 3 "/zxbasic/src/arch/zx48k/library-asm/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 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core +__IN_SCREEN: + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits + 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 10 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm" + push namespace core ; Sets the attribute at a given screen pixel address in hl ; HL contains the address in RAM for a given pixel (not a coordinate) SET_PIXEL_ADDR_ATTR: @@ -264,12 +258,11 @@ SET_PIXEL_ADDR_ATTR: rrca rrca and 3 - or 18h ld h, a - ld de, (SCREEN_ADDR) + ld de, (SCREEN_ATTR_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 - pop namespace + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelDown.asm" ; @@ -678,7 +671,7 @@ __FASTPLOTEND: ret ENDP pop namespace -#line 45 "draw.bas" +#line 45 "zx48k/draw.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -777,5 +770,5 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 46 "draw.bas" +#line 46 "zx48k/draw.bas" END diff --git a/tests/functional/zx48k/draw3.asm b/tests/functional/zx48k/draw3.asm index 1b6cf5480..6b84c8c91 100644 --- a/tests/functional/zx48k/draw3.asm +++ b/tests/functional/zx48k/draw3.asm @@ -149,125 +149,51 @@ __STOP: ; X in top of the stack #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" - push namespace core -__IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret - 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address + ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address add hl, de ; Return current screen address in HL ret @@ -278,10 +204,11 @@ 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 - call __ATTR_ADDR __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 @@ -294,6 +221,73 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address ld (hl), a ; Store result in screen ret ENDP + pop namespace +#line 3 "/zxbasic/src/arch/zx48k/library-asm/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 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core +__IN_SCREEN: + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits + 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm" + push namespace core ; Sets the attribute at a given screen pixel address in hl ; HL contains the address in RAM for a given pixel (not a coordinate) SET_PIXEL_ADDR_ATTR: @@ -303,12 +297,11 @@ SET_PIXEL_ADDR_ATTR: rrca rrca and 3 - or 18h ld h, a - ld de, (SCREEN_ADDR) + ld de, (SCREEN_ATTR_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 - pop namespace + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" push namespace core PLOT: @@ -1205,7 +1198,7 @@ SUM_B: jp __DRAW ;;forward to LINE-DRAW (Fastcalled) ENDP pop namespace -#line 75 "draw3.bas" +#line 75 "zx48k/draw3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -1304,5 +1297,5 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 76 "draw3.bas" +#line 76 "zx48k/draw3.bas" END diff --git a/tests/functional/zx48k/einarattr.asm b/tests/functional/zx48k/einarattr.asm index fae9c78a1..07d9bb352 100644 --- a/tests/functional/zx48k/einarattr.asm +++ b/tests/functional/zx48k/einarattr.asm @@ -69,77 +69,40 @@ _printA__leave: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -174,22 +137,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -198,7 +159,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -215,22 +262,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -264,7 +299,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -304,7 +339,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -341,7 +376,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -378,7 +413,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -417,7 +452,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -445,7 +480,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -473,7 +508,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -503,67 +538,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -572,68 +547,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -642,7 +610,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -657,71 +625,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -754,109 +715,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -864,10 +818,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -891,6 +847,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -898,20 +860,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -932,28 +885,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1034,7 +980,7 @@ __REFRESH_TMP: ret ENDP pop namespace -#line 43 "einarattr.bas" +#line 43 "zx48k/einarattr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1345,5 +1291,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 46 "einarattr.bas" +#line 46 "zx48k/einarattr.bas" END diff --git a/tests/functional/zx48k/einarshift.asm b/tests/functional/zx48k/einarshift.asm index f76fda0df..4fefd265c 100644 --- a/tests/functional/zx48k/einarshift.asm +++ b/tests/functional/zx48k/einarshift.asm @@ -55,77 +55,40 @@ _b: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -160,22 +123,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -184,7 +145,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -201,22 +248,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -250,7 +285,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -290,7 +325,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -327,7 +362,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -364,7 +399,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -457,7 +492,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -485,7 +520,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -513,7 +548,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -543,67 +578,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -612,68 +587,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -682,7 +650,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -697,71 +665,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -794,109 +755,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -904,10 +858,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -931,6 +887,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -938,20 +900,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -972,28 +925,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1021,7 +967,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 31 "einarshift.bas" +#line 31 "zx48k/einarshift.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1042,7 +988,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1143,5 +1089,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 32 "einarshift.bas" +#line 32 "zx48k/einarshift.bas" END diff --git a/tests/functional/zx48k/fact.asm b/tests/functional/zx48k/fact.asm index 485878513..c070d2ee4 100644 --- a/tests/functional/zx48k/fact.asm +++ b/tests/functional/zx48k/fact.asm @@ -136,71 +136,63 @@ _fact__leave: DEFB 20h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation -#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + ;; Clears the user screen (24 rows) +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 4 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace -#line 109 "fact.bas" +#line 109 "zx48k/fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" ; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223 @@ -283,13 +275,15 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) ld l, c ret pop namespace -#line 110 "fact.bas" +#line 110 "zx48k/fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -324,22 +318,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -348,7 +340,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -365,22 +443,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -414,7 +480,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -454,7 +520,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -491,7 +557,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -528,7 +594,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -621,7 +687,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -649,7 +715,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -677,7 +743,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -707,67 +773,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -776,68 +782,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -846,7 +845,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -861,71 +860,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -958,109 +950,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1068,10 +1053,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1095,6 +1082,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1102,20 +1095,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1136,28 +1120,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1185,7 +1162,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 111 "fact.bas" +#line 111 "zx48k/fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1496,7 +1473,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 112 "fact.bas" +#line 112 "zx48k/fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1517,7 +1494,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1697,7 +1674,7 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" -#line 113 "fact.bas" +#line 113 "zx48k/fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" @@ -1795,7 +1772,7 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 114 "fact.bas" +#line 114 "zx48k/fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sub32.asm" ; SUB32 ; Perform TOP of the stack - DEHL @@ -1822,5 +1799,5 @@ __SUB32: exx ret pop namespace -#line 115 "fact.bas" +#line 115 "zx48k/fact.bas" END diff --git a/tests/functional/zx48k/for0.asm b/tests/functional/zx48k/for0.asm index a4cd4d4b2..0bc025fc6 100644 --- a/tests/functional/zx48k/for0.asm +++ b/tests/functional/zx48k/for0.asm @@ -67,71 +67,63 @@ _x: DEFB 20h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation -#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + ;; Clears the user screen (24 rows) +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 4 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace -#line 40 "for0.bas" +#line 40 "zx48k/for0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" push namespace core @@ -156,15 +148,17 @@ checkParity: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" -#line 41 "for0.bas" +#line 41 "zx48k/for0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -199,22 +193,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -223,7 +215,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -240,22 +318,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -289,7 +355,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -329,7 +395,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -366,7 +432,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -403,7 +469,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -496,7 +562,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -524,7 +590,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -552,7 +618,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -582,67 +648,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -651,68 +657,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -721,7 +720,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -736,71 +735,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -833,109 +825,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -943,10 +928,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -970,6 +957,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -977,20 +970,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1011,28 +995,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1078,7 +1055,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1178,7 +1155,7 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 42 "for0.bas" +#line 42 "zx48k/for0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1489,5 +1466,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 43 "for0.bas" +#line 43 "zx48k/for0.bas" END diff --git a/tests/functional/zx48k/ifelse1.asm b/tests/functional/zx48k/ifelse1.asm index c69c56379..bbeaac0b5 100644 --- a/tests/functional/zx48k/ifelse1.asm +++ b/tests/functional/zx48k/ifelse1.asm @@ -68,77 +68,40 @@ _a: DEFB 21h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -173,22 +136,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -197,7 +158,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -214,22 +261,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -263,7 +298,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -303,7 +338,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -340,7 +375,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -377,7 +412,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -470,7 +505,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -498,7 +533,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -526,7 +561,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -556,67 +591,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -625,68 +600,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -695,7 +663,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -710,71 +678,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -807,109 +768,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -917,10 +871,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -944,6 +900,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -951,20 +913,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -985,28 +938,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1034,7 +980,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 41 "ifelse1.bas" +#line 41 "zx48k/ifelse1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1345,5 +1291,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 42 "ifelse1.bas" +#line 42 "zx48k/ifelse1.bas" END diff --git a/tests/functional/zx48k/ifwhilex.asm b/tests/functional/zx48k/ifwhilex.asm index 69a4ec28a..63a8c2e03 100644 --- a/tests/functional/zx48k/ifwhilex.asm +++ b/tests/functional/zx48k/ifwhilex.asm @@ -81,79 +81,42 @@ checkParity: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" -#line 36 "ifwhilex.bas" +#line 36 "zx48k/ifwhilex.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -188,22 +151,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -212,7 +173,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -229,22 +276,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -278,7 +313,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -318,7 +353,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -355,7 +390,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -392,7 +427,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -485,7 +520,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -513,7 +548,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -541,7 +576,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -571,67 +606,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -640,68 +615,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -710,7 +678,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -725,71 +693,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -822,109 +783,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -932,10 +886,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -959,6 +915,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -966,20 +928,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1000,28 +953,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1049,7 +995,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 37 "ifwhilex.bas" +#line 37 "zx48k/ifwhilex.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" push namespace core @@ -1069,7 +1015,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1169,5 +1115,5 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 38 "ifwhilex.bas" +#line 38 "zx48k/ifwhilex.bas" END diff --git a/tests/functional/zx48k/inkey.asm b/tests/functional/zx48k/inkey.asm index 111770699..e308fe9cd 100644 --- a/tests/functional/zx48k/inkey.asm +++ b/tests/functional/zx48k/inkey.asm @@ -405,94 +405,55 @@ __EMPTY_INKEY: KEY_CODE EQU 0333h ENDP pop namespace -#line 29 "inkey.bas" +#line 29 "zx48k/inkey.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -501,7 +462,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -518,22 +565,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -567,7 +602,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -607,7 +642,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -644,7 +679,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -681,7 +716,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -774,7 +809,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -802,7 +837,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -830,7 +865,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -860,67 +895,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -929,68 +904,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -999,7 +967,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1014,71 +982,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1111,109 +1072,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1221,10 +1175,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1248,6 +1204,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1255,20 +1217,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1289,28 +1242,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1338,7 +1284,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 30 "inkey.bas" +#line 30 "zx48k/inkey.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes @@ -1347,7 +1293,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 31 "inkey.bas" +#line 31 "zx48k/inkey.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1550,7 +1496,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 32 "inkey.bas" +#line 32 "zx48k/inkey.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when ; the value of B$ if already duplicated onto the stack. @@ -1584,5 +1530,5 @@ __STORE_STR2: dec hl ; HL points to mem address variable. This might be useful in the future. ret pop namespace -#line 33 "inkey.bas" +#line 33 "zx48k/inkey.bas" END diff --git a/tests/functional/zx48k/inktemp.asm b/tests/functional/zx48k/inktemp.asm index e464a6f89..5fb5bd5a9 100644 --- a/tests/functional/zx48k/inktemp.asm +++ b/tests/functional/zx48k/inktemp.asm @@ -105,125 +105,51 @@ __STOP: ; X in top of the stack #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" - push namespace core -__IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret - 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address + ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address add hl, de ; Return current screen address in HL ret @@ -234,10 +160,11 @@ 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 - call __ATTR_ADDR __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 @@ -250,6 +177,73 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address ld (hl), a ; Store result in screen ret ENDP + pop namespace +#line 3 "/zxbasic/src/arch/zx48k/library-asm/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 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core +__IN_SCREEN: + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits + 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm" + push namespace core ; Sets the attribute at a given screen pixel address in hl ; HL contains the address in RAM for a given pixel (not a coordinate) SET_PIXEL_ADDR_ATTR: @@ -259,12 +253,11 @@ SET_PIXEL_ADDR_ATTR: rrca rrca and 3 - or 18h ld h, a - ld de, (SCREEN_ADDR) + ld de, (SCREEN_ATTR_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 - pop namespace + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" push namespace core PLOT: @@ -490,7 +483,7 @@ __CIRCLE_PLOT: ret ENDP pop namespace -#line 42 "inktemp.bas" +#line 42 "zx48k/inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" push namespace core @@ -521,7 +514,7 @@ __REFRESH_TMP: ret ENDP pop namespace -#line 43 "inktemp.bas" +#line 43 "zx48k/inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" ; DRAW using bresenhams algorithm and screen positioning ; Copyleft (k) 2010 by J. Rodriguez (a.k.a. Boriel) http://www.boriel.com @@ -935,7 +928,7 @@ __FASTPLOTEND: ret ENDP pop namespace -#line 44 "inktemp.bas" +#line 44 "zx48k/inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -972,7 +965,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 45 "inktemp.bas" +#line 45 "zx48k/inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register @@ -1009,7 +1002,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 46 "inktemp.bas" +#line 46 "zx48k/inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -1048,7 +1041,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 47 "inktemp.bas" +#line 47 "zx48k/inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -1088,5 +1081,5 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 48 "inktemp.bas" +#line 48 "zx48k/inktemp.bas" END diff --git a/tests/functional/zx48k/label_sent2.asm b/tests/functional/zx48k/label_sent2.asm index c44c5a11c..2ceec750f 100644 --- a/tests/functional/zx48k/label_sent2.asm +++ b/tests/functional/zx48k/label_sent2.asm @@ -49,20 +49,35 @@ BORDER EQU 229Bh pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) -#line 24 "label_sent2.bas" +#line 24 "zx48k/label_sent2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" push namespace core COPY_ATTR: @@ -92,7 +107,7 @@ __REFRESH_TMP: ret ENDP pop namespace -#line 25 "label_sent2.bas" +#line 25 "zx48k/label_sent2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -132,5 +147,5 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 26 "label_sent2.bas" +#line 26 "zx48k/label_sent2.bas" END diff --git a/tests/functional/zx48k/label_sent3.asm b/tests/functional/zx48k/label_sent3.asm index ec3a1029d..8f77de7af 100644 --- a/tests/functional/zx48k/label_sent3.asm +++ b/tests/functional/zx48k/label_sent3.asm @@ -49,20 +49,35 @@ BORDER EQU 229Bh pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) -#line 24 "label_sent3.bas" +#line 24 "zx48k/label_sent3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" push namespace core COPY_ATTR: @@ -92,7 +107,7 @@ __REFRESH_TMP: ret ENDP pop namespace -#line 25 "label_sent3.bas" +#line 25 "zx48k/label_sent3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -132,5 +147,5 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 26 "label_sent3.bas" +#line 26 "zx48k/label_sent3.bas" END diff --git a/tests/functional/zx48k/label_sent4.asm b/tests/functional/zx48k/label_sent4.asm index d7d0c4e39..dc84d4e84 100644 --- a/tests/functional/zx48k/label_sent4.asm +++ b/tests/functional/zx48k/label_sent4.asm @@ -49,20 +49,35 @@ BORDER EQU 229Bh pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) -#line 24 "label_sent4.bas" +#line 24 "zx48k/label_sent4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" push namespace core COPY_ATTR: @@ -92,7 +107,7 @@ __REFRESH_TMP: ret ENDP pop namespace -#line 25 "label_sent4.bas" +#line 25 "zx48k/label_sent4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -132,5 +147,5 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 26 "label_sent4.bas" +#line 26 "zx48k/label_sent4.bas" END diff --git a/tests/functional/zx48k/label_sent5.asm b/tests/functional/zx48k/label_sent5.asm index d002bcfe3..6c478fdb2 100644 --- a/tests/functional/zx48k/label_sent5.asm +++ b/tests/functional/zx48k/label_sent5.asm @@ -49,20 +49,35 @@ BORDER EQU 229Bh pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) -#line 24 "label_sent5.bas" +#line 24 "zx48k/label_sent5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" push namespace core COPY_ATTR: @@ -92,7 +107,7 @@ __REFRESH_TMP: ret ENDP pop namespace -#line 25 "label_sent5.bas" +#line 25 "zx48k/label_sent5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -132,5 +147,5 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 26 "label_sent5.bas" +#line 26 "zx48k/label_sent5.bas" END diff --git a/tests/functional/zx48k/lcd3.asm b/tests/functional/zx48k/lcd3.asm index 41bf9da83..e6daaf0bf 100644 --- a/tests/functional/zx48k/lcd3.asm +++ b/tests/functional/zx48k/lcd3.asm @@ -224,7 +224,7 @@ __ADDF: ; Addition defb 38h; ; END CALC jp __FPSTACK_POP pop namespace -#line 140 "lcd3.bas" +#line 140 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa @@ -491,7 +491,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 141 "lcd3.bas" +#line 141 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -590,7 +590,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 142 "lcd3.bas" +#line 142 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -821,94 +821,55 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 143 "lcd3.bas" +#line 143 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -917,7 +878,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -934,22 +981,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -983,7 +1018,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -1023,7 +1058,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -1060,7 +1095,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -1097,7 +1132,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -1190,7 +1225,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -1218,7 +1253,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1246,7 +1281,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1276,67 +1311,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1345,68 +1320,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1415,7 +1383,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1430,71 +1398,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1527,109 +1488,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1637,10 +1591,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1664,6 +1620,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1671,20 +1633,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1705,28 +1658,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1754,7 +1700,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 144 "lcd3.bas" +#line 144 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1798,7 +1744,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 145 "lcd3.bas" +#line 145 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr2.asm" ; vim:ts=4:et:sw=4 ; @@ -1847,7 +1793,7 @@ __PSTORE_STR2: add hl, bc jp __STORE_STR2 pop namespace -#line 146 "lcd3.bas" +#line 146 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last @@ -1875,7 +1821,7 @@ __FP_PUSH_REV: exx ret pop namespace -#line 147 "lcd3.bas" +#line 147 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation ; Given a FP number in C ED LH @@ -1932,7 +1878,7 @@ __STR_END: STK_END EQU 5C65h ENDP pop namespace -#line 148 "lcd3.bas" +#line 148 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string @@ -2045,7 +1991,7 @@ __STRCATEND: ret ENDP pop namespace -#line 149 "lcd3.bas" +#line 149 "zx48k/lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" push namespace core __I8TOFREG: @@ -2116,5 +2062,5 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 151 "lcd3.bas" +#line 151 "zx48k/lcd3.bas" END diff --git a/tests/functional/zx48k/lcd7.asm b/tests/functional/zx48k/lcd7.asm index c1132c54a..ecee28f72 100644 --- a/tests/functional/zx48k/lcd7.asm +++ b/tests/functional/zx48k/lcd7.asm @@ -361,7 +361,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 71 "lcd7.bas" +#line 71 "zx48k/lcd7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -592,97 +592,58 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 72 "lcd7.bas" +#line 72 "zx48k/lcd7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -691,7 +652,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -708,22 +755,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -757,7 +792,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -797,7 +832,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -834,7 +869,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -871,7 +906,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -964,7 +999,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -992,7 +1027,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1020,7 +1055,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1050,67 +1085,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1119,68 +1094,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1189,7 +1157,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1204,71 +1172,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1301,109 +1262,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1411,10 +1365,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1438,6 +1394,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1445,20 +1407,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1479,28 +1432,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1534,7 +1480,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 73 "lcd7.bas" +#line 73 "zx48k/lcd7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1578,7 +1524,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 74 "lcd7.bas" +#line 74 "zx48k/lcd7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 ; @@ -1841,5 +1787,5 @@ __PSTORE_STR: add hl, bc jp __STORE_STR pop namespace -#line 75 "lcd7.bas" +#line 75 "zx48k/lcd7.bas" END diff --git a/tests/functional/zx48k/lcd8.asm b/tests/functional/zx48k/lcd8.asm index f1fa30897..afd510cdb 100644 --- a/tests/functional/zx48k/lcd8.asm +++ b/tests/functional/zx48k/lcd8.asm @@ -363,7 +363,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 73 "lcd8.bas" +#line 73 "zx48k/lcd8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -594,97 +594,58 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 74 "lcd8.bas" +#line 74 "zx48k/lcd8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -693,7 +654,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -710,22 +757,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -759,7 +794,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -799,7 +834,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -836,7 +871,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -873,7 +908,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -966,7 +1001,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -994,7 +1029,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1022,7 +1057,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1052,67 +1087,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1121,68 +1096,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1191,7 +1159,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1206,71 +1174,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1303,109 +1264,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1413,10 +1367,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1440,6 +1396,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1447,20 +1409,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1481,28 +1434,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1536,7 +1482,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 75 "lcd8.bas" +#line 75 "zx48k/lcd8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1580,5 +1526,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 76 "lcd8.bas" +#line 76 "zx48k/lcd8.bas" END diff --git a/tests/functional/zx48k/lcd9.asm b/tests/functional/zx48k/lcd9.asm index b83385616..a5466aedd 100644 --- a/tests/functional/zx48k/lcd9.asm +++ b/tests/functional/zx48k/lcd9.asm @@ -353,7 +353,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 61 "lcd9.bas" +#line 61 "zx48k/lcd9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -584,97 +584,58 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 62 "lcd9.bas" +#line 62 "zx48k/lcd9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -683,7 +644,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -700,22 +747,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -749,7 +784,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -789,7 +824,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -826,7 +861,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -863,7 +898,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -956,7 +991,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -984,7 +1019,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1012,7 +1047,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1042,67 +1077,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1111,68 +1086,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1181,7 +1149,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1196,71 +1164,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1293,109 +1254,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1403,10 +1357,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1430,6 +1386,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1437,20 +1399,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1471,28 +1424,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1526,7 +1472,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 63 "lcd9.bas" +#line 63 "zx48k/lcd9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1570,7 +1516,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 64 "lcd9.bas" +#line 64 "zx48k/lcd9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 ; Stores value of current string pointed by DE register into address pointed by HL @@ -1819,5 +1765,5 @@ __STORE_STR: pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret pop namespace -#line 65 "lcd9.bas" +#line 65 "zx48k/lcd9.bas" END diff --git a/tests/functional/zx48k/let_array_local_const0.asm b/tests/functional/zx48k/let_array_local_const0.asm index 932ca8a1e..8c2effe50 100644 --- a/tests/functional/zx48k/let_array_local_const0.asm +++ b/tests/functional/zx48k/let_array_local_const0.asm @@ -266,7 +266,7 @@ TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables ENDP pop namespace -#line 99 "let_array_local_const0.bas" +#line 99 "zx48k/let_array_local_const0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; vim: ts=4:et:sw=4: @@ -679,7 +679,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ret #line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" pop namespace -#line 100 "let_array_local_const0.bas" +#line 100 "zx48k/let_array_local_const0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa @@ -838,96 +838,57 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 101 "let_array_local_const0.bas" +#line 101 "zx48k/let_array_local_const0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -936,7 +897,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -953,22 +1000,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -1002,7 +1037,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -1042,7 +1077,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -1079,7 +1114,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -1116,7 +1151,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -1209,7 +1244,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -1237,7 +1272,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1265,7 +1300,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1295,67 +1330,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1364,68 +1339,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1434,7 +1402,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1449,71 +1417,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1546,109 +1507,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1656,10 +1610,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1683,6 +1639,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1690,20 +1652,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1724,28 +1677,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1791,7 +1737,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1891,7 +1837,7 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 102 "let_array_local_const0.bas" +#line 102 "zx48k/let_array_local_const0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1935,7 +1881,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 103 "let_array_local_const0.bas" +#line 103 "zx48k/let_array_local_const0.bas" .LABEL.__LABEL6: DEFB 00h DEFB 00h diff --git a/tests/functional/zx48k/load02.asm b/tests/functional/zx48k/load02.asm index 489e9b36b..9eac0f648 100644 --- a/tests/functional/zx48k/load02.asm +++ b/tests/functional/zx48k/load02.asm @@ -329,77 +329,40 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -434,22 +397,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -458,7 +419,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -475,22 +522,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -524,7 +559,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -564,7 +599,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -601,7 +636,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -638,7 +673,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -708,7 +743,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -736,7 +771,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -764,7 +799,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -794,67 +829,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -863,68 +838,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -933,7 +901,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -948,71 +916,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1045,109 +1006,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1155,10 +1109,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1182,6 +1138,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1189,20 +1151,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1223,28 +1176,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1529,7 +1475,7 @@ PRINT_TAPE_MSG: ENDP #line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" pop namespace -#line 34 "load02.bas" +#line 34 "zx48k/load02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -1725,5 +1671,5 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 35 "load02.bas" +#line 35 "zx48k/load02.bas" END diff --git a/tests/functional/zx48k/load03.asm b/tests/functional/zx48k/load03.asm index c2aecd39f..f4111bdcc 100644 --- a/tests/functional/zx48k/load03.asm +++ b/tests/functional/zx48k/load03.asm @@ -326,77 +326,40 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -431,22 +394,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -455,7 +416,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -472,22 +519,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -521,7 +556,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -561,7 +596,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -598,7 +633,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -635,7 +670,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -705,7 +740,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -733,7 +768,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -761,7 +796,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -791,67 +826,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -860,68 +835,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -930,7 +898,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -945,71 +913,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1042,109 +1003,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1152,10 +1106,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1179,6 +1135,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1186,20 +1148,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1220,28 +1173,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1526,7 +1472,7 @@ PRINT_TAPE_MSG: ENDP #line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" pop namespace -#line 33 "load03.bas" +#line 33 "zx48k/load03.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -1722,5 +1668,5 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 34 "load03.bas" +#line 34 "zx48k/load03.bas" END diff --git a/tests/functional/zx48k/loadstr.asm b/tests/functional/zx48k/loadstr.asm index d2a24cf2d..239b11ed4 100644 --- a/tests/functional/zx48k/loadstr.asm +++ b/tests/functional/zx48k/loadstr.asm @@ -766,7 +766,7 @@ __STORE_STR: pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret pop namespace -#line 31 "loadstr.bas" +#line 31 "zx48k/loadstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when ; the value of B$ if already duplicated onto the stack. @@ -800,7 +800,7 @@ __STORE_STR2: dec hl ; HL points to mem address variable. This might be useful in the future. ret pop namespace -#line 32 "loadstr.bas" +#line 32 "zx48k/loadstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation ; Given a FP number in C ED LH @@ -846,17 +846,32 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK jp __FPSTACK_PUSH pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 10 "/zxbasic/src/arch/zx48k/library-asm/str.asm" push namespace core __STR: @@ -909,7 +924,7 @@ __STR_END: STK_END EQU 5C65h ENDP pop namespace -#line 33 "loadstr.bas" +#line 33 "zx48k/loadstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/val.asm" push namespace core VAL: ; Computes VAL(a$) using ROM FP-CALC @@ -1001,5 +1016,5 @@ __RET_ZERO: ; Returns 0 Floating point on error ret ENDP pop namespace -#line 34 "loadstr.bas" +#line 34 "zx48k/loadstr.bas" END diff --git a/tests/functional/zx48k/loadu16ii.asm b/tests/functional/zx48k/loadu16ii.asm index 63e02fc0f..b33287818 100644 --- a/tests/functional/zx48k/loadu16ii.asm +++ b/tests/functional/zx48k/loadu16ii.asm @@ -53,9 +53,9 @@ ei ret .LABEL._test: -#line 6 "loadu16ii.bas" +#line 5 "zx48k/loadu16ii.bas" defw 35600 -#line 8 "loadu16ii.bas" +#line 8 "zx48k/loadu16ii.bas" ld hl, 0 ld b, h ld c, l @@ -87,79 +87,42 @@ __MUL16NOADD: ret ; Result in hl (16 lower bits) ENDP pop namespace -#line 15 "loadu16ii.bas" +#line 15 "zx48k/loadu16ii.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -194,22 +157,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -218,7 +179,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -235,22 +282,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -284,7 +319,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -324,7 +359,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -361,7 +396,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -398,7 +433,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -491,7 +526,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -519,7 +554,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -547,7 +582,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -577,67 +612,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -646,68 +621,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -716,7 +684,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -731,71 +699,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -828,109 +789,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -938,10 +892,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -965,6 +921,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -972,20 +934,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1006,28 +959,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1055,7 +1001,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 16 "loadu16ii.bas" +#line 16 "zx48k/loadu16ii.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1076,7 +1022,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1203,5 +1149,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 17 "loadu16ii.bas" +#line 17 "zx48k/loadu16ii.bas" END diff --git a/tests/functional/zx48k/ltee1.asm b/tests/functional/zx48k/ltee1.asm index 1c6b5cd64..b21e63985 100644 --- a/tests/functional/zx48k/ltee1.asm +++ b/tests/functional/zx48k/ltee1.asm @@ -378,7 +378,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 86 "ltee1.bas" +#line 86 "zx48k/ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -609,97 +609,58 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 87 "ltee1.bas" +#line 87 "zx48k/ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -708,7 +669,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -725,22 +772,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -774,7 +809,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -814,7 +849,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -851,7 +886,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -888,7 +923,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -981,7 +1016,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -1009,7 +1044,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1037,7 +1072,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1067,67 +1102,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1136,68 +1111,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1206,7 +1174,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1221,71 +1189,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1318,109 +1279,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1428,10 +1382,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1455,6 +1411,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1462,20 +1424,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1496,28 +1449,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1551,7 +1497,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 88 "ltee1.bas" +#line 88 "zx48k/ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1595,7 +1541,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 89 "ltee1.bas" +#line 89 "zx48k/ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 ; @@ -1858,7 +1804,7 @@ __PSTORE_STR: add hl, bc jp __STORE_STR pop namespace -#line 90 "ltee1.bas" +#line 90 "zx48k/ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr2.asm" ; vim:ts=4:et:sw=4 ; @@ -1907,7 +1853,7 @@ __PSTORE_STR2: add hl, bc jp __STORE_STR2 pop namespace -#line 91 "ltee1.bas" +#line 91 "zx48k/ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string @@ -2020,5 +1966,5 @@ __STRCATEND: ret ENDP pop namespace -#line 93 "ltee1.bas" +#line 93 "zx48k/ltee1.bas" END diff --git a/tests/functional/zx48k/memcpytest.asm b/tests/functional/zx48k/memcpytest.asm index b86f1115c..27570621f 100644 --- a/tests/functional/zx48k/memcpytest.asm +++ b/tests/functional/zx48k/memcpytest.asm @@ -75,7 +75,7 @@ _i: ei ret _MemMove: -#line 32 "/zxbasic/src/arch/zx48k/library/memcopy.bas" +#line 31 "/zxbasic/src/arch/zx48k/library/memcopy.bas" push namespace core exx pop hl @@ -91,7 +91,7 @@ _MemMove: _MemMove__leave: ret _MemCopy: -#line 68 "/zxbasic/src/arch/zx48k/library/memcopy.bas" +#line 67 "/zxbasic/src/arch/zx48k/library/memcopy.bas" push namespace core exx pop hl @@ -107,7 +107,7 @@ _MemCopy: _MemCopy__leave: ret _MemSet: -#line 101 "/zxbasic/src/arch/zx48k/library/memcopy.bas" +#line 100 "/zxbasic/src/arch/zx48k/library/memcopy.bas" push namespace core pop de pop af @@ -135,68 +135,60 @@ _MemSet__leave: DEFB 20h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation -#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + ;; Clears the user screen (24 rows) +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 4 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace #line 134 "/zxbasic/src/arch/zx48k/library/memcopy.bas" @@ -253,11 +245,13 @@ __PAUSE: #line 136 "/zxbasic/src/arch/zx48k/library/memcopy.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -292,22 +286,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -316,7 +308,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -333,22 +411,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -382,7 +448,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -422,7 +488,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -459,7 +525,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -496,7 +562,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -589,7 +655,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -617,7 +683,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -645,7 +711,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -675,67 +741,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -744,68 +750,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -814,7 +813,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -829,71 +828,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -926,109 +918,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1036,10 +1021,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1063,6 +1050,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1070,20 +1063,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1104,28 +1088,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 diff --git a/tests/functional/zx48k/noheap.asm b/tests/functional/zx48k/noheap.asm index 264a59978..d04ac7cd6 100644 --- a/tests/functional/zx48k/noheap.asm +++ b/tests/functional/zx48k/noheap.asm @@ -40,77 +40,40 @@ ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -145,22 +108,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -169,7 +130,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -186,22 +233,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -235,7 +270,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -275,7 +310,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -312,7 +347,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -349,7 +384,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -442,7 +477,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -470,7 +505,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -498,7 +533,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -528,67 +563,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -597,68 +572,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -667,7 +635,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -682,71 +650,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -779,109 +740,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -889,10 +843,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -916,6 +872,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -923,20 +885,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -957,28 +910,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1006,7 +952,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 20 "noheap.bas" +#line 20 "zx48k/noheap.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1027,7 +973,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1154,5 +1100,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 21 "noheap.bas" +#line 21 "zx48k/noheap.bas" END diff --git a/tests/functional/zx48k/ongosub.asm b/tests/functional/zx48k/ongosub.asm index a59224a37..a86569625 100644 --- a/tests/functional/zx48k/ongosub.asm +++ b/tests/functional/zx48k/ongosub.asm @@ -142,79 +142,42 @@ __ON_GOTO_START: ld l, a jp (hl) pop namespace -#line 85 "ongosub.bas" +#line 85 "zx48k/ongosub.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -249,22 +212,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -273,7 +234,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -290,22 +337,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -339,7 +374,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -379,7 +414,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -416,7 +451,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -453,7 +488,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -546,7 +581,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -574,7 +609,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -602,7 +637,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -632,67 +667,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -701,68 +676,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -771,7 +739,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -786,71 +754,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -883,109 +844,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -993,10 +947,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1020,6 +976,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1027,20 +989,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1061,28 +1014,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1110,7 +1056,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 86 "ongosub.bas" +#line 86 "zx48k/ongosub.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1421,5 +1367,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 87 "ongosub.bas" +#line 87 "zx48k/ongosub.bas" END diff --git a/tests/functional/zx48k/ongoto.asm b/tests/functional/zx48k/ongoto.asm index 015695dc8..3ee797aa1 100644 --- a/tests/functional/zx48k/ongoto.asm +++ b/tests/functional/zx48k/ongoto.asm @@ -120,79 +120,42 @@ __ON_GOTO_START: ld l, a jp (hl) pop namespace -#line 63 "ongoto.bas" +#line 63 "zx48k/ongoto.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -227,22 +190,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -251,7 +212,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -268,22 +315,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -317,7 +352,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -357,7 +392,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -394,7 +429,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -431,7 +466,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -524,7 +559,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -552,7 +587,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -580,7 +615,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -610,67 +645,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -679,68 +654,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -749,7 +717,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -764,71 +732,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -861,109 +822,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -971,10 +925,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -998,6 +954,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1005,20 +967,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1039,28 +992,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1088,7 +1034,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 64 "ongoto.bas" +#line 64 "zx48k/ongoto.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1399,5 +1345,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 65 "ongoto.bas" +#line 65 "zx48k/ongoto.bas" END diff --git a/tests/functional/zx48k/opt1_dim_arr_global.asm b/tests/functional/zx48k/opt1_dim_arr_global.asm index 985edea1b..04990f79d 100644 --- a/tests/functional/zx48k/opt1_dim_arr_global.asm +++ b/tests/functional/zx48k/opt1_dim_arr_global.asm @@ -192,79 +192,42 @@ TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables ENDP pop namespace -#line 25 "opt1_dim_arr_global.bas" +#line 25 "zx48k/opt1_dim_arr_global.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -299,22 +262,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -323,7 +284,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -340,22 +387,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -389,7 +424,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -429,7 +464,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -466,7 +501,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -503,7 +538,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -596,7 +631,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -624,7 +659,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -652,7 +687,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -682,67 +717,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -751,68 +726,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -821,7 +789,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -836,71 +804,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -933,109 +894,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1043,10 +997,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1070,6 +1026,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1077,20 +1039,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1111,28 +1064,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1160,7 +1106,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 26 "opt1_dim_arr_global.bas" +#line 26 "zx48k/opt1_dim_arr_global.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1181,7 +1127,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1282,5 +1228,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 27 "opt1_dim_arr_global.bas" +#line 27 "zx48k/opt1_dim_arr_global.bas" END diff --git a/tests/functional/zx48k/opt1_dim_arr_global2.asm b/tests/functional/zx48k/opt1_dim_arr_global2.asm index c7cdd2c05..a6d94d530 100644 --- a/tests/functional/zx48k/opt1_dim_arr_global2.asm +++ b/tests/functional/zx48k/opt1_dim_arr_global2.asm @@ -54,77 +54,40 @@ _a.__DATA__: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -159,22 +122,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -183,7 +144,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -200,22 +247,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -249,7 +284,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -289,7 +324,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -326,7 +361,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -363,7 +398,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -456,7 +491,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -484,7 +519,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -512,7 +547,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -542,67 +577,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -611,68 +586,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -681,7 +649,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -696,71 +664,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -793,109 +754,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -903,10 +857,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -930,6 +886,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -937,20 +899,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -971,28 +924,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1020,7 +966,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 20 "opt1_dim_arr_global2.bas" +#line 20 "zx48k/opt1_dim_arr_global2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1041,7 +987,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1142,5 +1088,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 21 "opt1_dim_arr_global2.bas" +#line 21 "zx48k/opt1_dim_arr_global2.bas" END diff --git a/tests/functional/zx48k/opt1_dim_arr_global3.asm b/tests/functional/zx48k/opt1_dim_arr_global3.asm index 230f3c6bc..2d223f1b8 100644 --- a/tests/functional/zx48k/opt1_dim_arr_global3.asm +++ b/tests/functional/zx48k/opt1_dim_arr_global3.asm @@ -55,77 +55,40 @@ _a.__DATA__: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -160,22 +123,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -184,7 +145,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -201,22 +248,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -250,7 +285,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -290,7 +325,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -327,7 +362,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -364,7 +399,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -457,7 +492,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -485,7 +520,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -513,7 +548,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -543,67 +578,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -612,68 +587,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -682,7 +650,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -697,71 +665,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -794,109 +755,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -904,10 +858,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -931,6 +887,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -938,20 +900,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -972,28 +925,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1021,7 +967,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 21 "opt1_dim_arr_global3.bas" +#line 21 "zx48k/opt1_dim_arr_global3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1042,7 +988,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1143,5 +1089,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 22 "opt1_dim_arr_global3.bas" +#line 22 "zx48k/opt1_dim_arr_global3.bas" END diff --git a/tests/functional/zx48k/opt1_dim_arr_global4.asm b/tests/functional/zx48k/opt1_dim_arr_global4.asm index 574722a45..905cd6a58 100644 --- a/tests/functional/zx48k/opt1_dim_arr_global4.asm +++ b/tests/functional/zx48k/opt1_dim_arr_global4.asm @@ -197,79 +197,42 @@ TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables ENDP pop namespace -#line 30 "opt1_dim_arr_global4.bas" +#line 30 "zx48k/opt1_dim_arr_global4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -304,22 +267,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -328,7 +289,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -345,22 +392,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -394,7 +429,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -434,7 +469,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -471,7 +506,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -508,7 +543,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -601,7 +636,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -629,7 +664,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -657,7 +692,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -687,67 +722,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -756,68 +731,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -826,7 +794,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -841,71 +809,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -938,109 +899,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1048,10 +1002,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1075,6 +1031,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1082,20 +1044,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1116,28 +1069,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1165,7 +1111,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 31 "opt1_dim_arr_global4.bas" +#line 31 "zx48k/opt1_dim_arr_global4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1186,7 +1132,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1287,5 +1233,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 32 "opt1_dim_arr_global4.bas" +#line 32 "zx48k/opt1_dim_arr_global4.bas" END diff --git a/tests/functional/zx48k/opt1_dim_arr_local2.asm b/tests/functional/zx48k/opt1_dim_arr_local2.asm index 8f1dcfde8..f48f15d4d 100644 --- a/tests/functional/zx48k/opt1_dim_arr_local2.asm +++ b/tests/functional/zx48k/opt1_dim_arr_local2.asm @@ -486,7 +486,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ret #line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" pop namespace -#line 50 "opt1_dim_arr_local2.bas" +#line 50 "zx48k/opt1_dim_arr_local2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa @@ -645,94 +645,55 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 51 "opt1_dim_arr_local2.bas" +#line 51 "zx48k/opt1_dim_arr_local2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -741,7 +702,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -758,22 +805,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -807,7 +842,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -847,7 +882,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -884,7 +919,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -921,7 +956,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -1014,7 +1049,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -1042,7 +1077,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1070,7 +1105,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1100,67 +1135,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1169,68 +1144,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1239,7 +1207,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1254,71 +1222,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1351,109 +1312,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1461,10 +1415,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1488,6 +1444,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1495,20 +1457,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1529,28 +1482,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1578,7 +1524,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 52 "opt1_dim_arr_local2.bas" +#line 52 "zx48k/opt1_dim_arr_local2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1599,7 +1545,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1700,7 +1646,7 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 53 "opt1_dim_arr_local2.bas" +#line 53 "zx48k/opt1_dim_arr_local2.bas" .LABEL.__LABEL0: DEFB 00h DEFB 00h diff --git a/tests/functional/zx48k/opt2_fastcall_func.asm b/tests/functional/zx48k/opt2_fastcall_func.asm index 0758457ae..ffdfebfe8 100644 --- a/tests/functional/zx48k/opt2_fastcall_func.asm +++ b/tests/functional/zx48k/opt2_fastcall_func.asm @@ -84,77 +84,40 @@ _c2__leave: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -189,22 +152,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -213,7 +174,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -230,22 +277,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -279,7 +314,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -319,7 +354,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -356,7 +391,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -393,7 +428,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -486,7 +521,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -514,7 +549,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -542,7 +577,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -572,67 +607,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -641,68 +616,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -711,7 +679,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -726,71 +694,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -823,109 +784,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -933,10 +887,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -960,6 +916,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -967,20 +929,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1001,28 +954,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1050,7 +996,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 64 "opt2_fastcall_func.bas" +#line 64 "zx48k/opt2_fastcall_func.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1071,7 +1017,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1172,5 +1118,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 65 "opt2_fastcall_func.bas" +#line 65 "zx48k/opt2_fastcall_func.bas" END diff --git a/tests/functional/zx48k/opt2_func_call.asm b/tests/functional/zx48k/opt2_func_call.asm index 30910f778..93933d77f 100644 --- a/tests/functional/zx48k/opt2_func_call.asm +++ b/tests/functional/zx48k/opt2_func_call.asm @@ -62,77 +62,40 @@ _c1__leave: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -167,22 +130,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -191,7 +152,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -208,22 +255,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -257,7 +292,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -297,7 +332,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -334,7 +369,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -371,7 +406,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -464,7 +499,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -492,7 +527,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -520,7 +555,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -550,67 +585,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -619,68 +594,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -689,7 +657,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -704,71 +672,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -801,109 +762,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -911,10 +865,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -938,6 +894,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -945,20 +907,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -979,28 +932,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1028,7 +974,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 42 "opt2_func_call.bas" +#line 42 "zx48k/opt2_func_call.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1049,7 +995,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1150,5 +1096,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 43 "opt2_func_call.bas" +#line 43 "zx48k/opt2_func_call.bas" END diff --git a/tests/functional/zx48k/opt3_data2.asm b/tests/functional/zx48k/opt3_data2.asm index 40d06afb5..bd9ae4889 100644 --- a/tests/functional/zx48k/opt3_data2.asm +++ b/tests/functional/zx48k/opt3_data2.asm @@ -272,7 +272,7 @@ TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables ENDP pop namespace -#line 96 "opt3_data2.bas" +#line 96 "zx48k/opt3_data2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" push namespace core __MUL8: ; Performs 8bit x 8bit multiplication @@ -319,79 +319,42 @@ __MUL8B: ret ; result = HL ENDP pop namespace -#line 97 "opt3_data2.bas" +#line 97 "zx48k/opt3_data2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -426,22 +389,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -450,7 +411,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -467,22 +514,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -516,7 +551,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -556,7 +591,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -593,7 +628,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -630,7 +665,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -723,7 +758,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -751,7 +786,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -779,7 +814,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -809,67 +844,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -878,68 +853,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -948,7 +916,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -963,71 +931,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1060,109 +1021,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1170,10 +1124,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1197,6 +1153,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1204,20 +1166,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1238,28 +1191,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1287,7 +1233,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 98 "opt3_data2.bas" +#line 98 "zx48k/opt3_data2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1308,7 +1254,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1409,7 +1355,7 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 99 "opt3_data2.bas" +#line 99 "zx48k/opt3_data2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2464,5 +2410,5 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 100 "opt3_data2.bas" +#line 100 "zx48k/opt3_data2.bas" END diff --git a/tests/functional/zx48k/opt3_einar.asm b/tests/functional/zx48k/opt3_einar.asm index 7755e933c..46a82feae 100644 --- a/tests/functional/zx48k/opt3_einar.asm +++ b/tests/functional/zx48k/opt3_einar.asm @@ -76,77 +76,40 @@ _x2__leave: DEFB 4Bh ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -181,22 +144,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -205,7 +166,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -222,22 +269,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -271,7 +306,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -311,7 +346,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -348,7 +383,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -385,7 +420,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -478,7 +513,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -506,7 +541,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -534,7 +569,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -564,67 +599,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -633,68 +608,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -703,7 +671,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -718,71 +686,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -815,109 +776,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -925,10 +879,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -952,6 +908,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -959,20 +921,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -993,28 +946,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1042,7 +988,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 51 "opt3_einar.bas" +#line 51 "zx48k/opt3_einar.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1353,5 +1299,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 52 "opt3_einar.bas" +#line 52 "zx48k/opt3_einar.bas" END diff --git a/tests/functional/zx48k/optconst.asm b/tests/functional/zx48k/optconst.asm index 7b0a66a09..31e65fd69 100644 --- a/tests/functional/zx48k/optconst.asm +++ b/tests/functional/zx48k/optconst.asm @@ -67,77 +67,40 @@ _a: jp .core.__END_PROGRAM ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -172,22 +135,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -196,7 +157,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -213,22 +260,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -262,7 +297,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -302,7 +337,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -339,7 +374,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -376,7 +411,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -469,7 +504,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -497,7 +532,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -525,7 +560,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -555,67 +590,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -624,68 +599,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -694,7 +662,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -709,71 +677,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -806,109 +767,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -916,10 +870,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -943,6 +899,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -950,20 +912,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -984,28 +937,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1033,7 +979,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 45 "optconst.bas" +#line 45 "zx48k/optconst.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1054,7 +1000,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1234,5 +1180,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" -#line 46 "optconst.bas" +#line 46 "zx48k/optconst.bas" END diff --git a/tests/functional/zx48k/param0.asm b/tests/functional/zx48k/param0.asm index 5db376d3b..340fcbafb 100644 --- a/tests/functional/zx48k/param0.asm +++ b/tests/functional/zx48k/param0.asm @@ -345,7 +345,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 55 "param0.bas" +#line 55 "zx48k/param0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -576,94 +576,55 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 56 "param0.bas" +#line 56 "zx48k/param0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -672,7 +633,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -689,22 +736,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -738,7 +773,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -778,7 +813,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -815,7 +850,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -852,7 +887,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -945,7 +980,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -973,7 +1008,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1001,7 +1036,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1031,67 +1066,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1100,68 +1075,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1170,7 +1138,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1185,71 +1153,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1282,109 +1243,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1392,10 +1346,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1419,6 +1375,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1426,20 +1388,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1460,28 +1413,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1509,7 +1455,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 57 "param0.bas" +#line 57 "zx48k/param0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1553,7 +1499,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 58 "param0.bas" +#line 58 "zx48k/param0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string @@ -1666,5 +1612,5 @@ __STRCATEND: ret ENDP pop namespace -#line 59 "param0.bas" +#line 59 "zx48k/param0.bas" END diff --git a/tests/functional/zx48k/param1.asm b/tests/functional/zx48k/param1.asm index cda015a96..98f425860 100644 --- a/tests/functional/zx48k/param1.asm +++ b/tests/functional/zx48k/param1.asm @@ -77,77 +77,40 @@ _test__leave: ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -182,22 +145,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -206,7 +167,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -223,22 +270,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -272,7 +307,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -312,7 +347,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -349,7 +384,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -386,7 +421,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -479,7 +514,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -507,7 +542,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -535,7 +570,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -565,67 +600,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -634,68 +609,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -704,7 +672,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -719,71 +687,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -816,109 +777,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -926,10 +880,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -953,6 +909,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -960,20 +922,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -994,28 +947,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1049,7 +995,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 47 "param1.bas" +#line 47 "zx48k/param1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1360,7 +1306,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 48 "param1.bas" +#line 48 "zx48k/param1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 ; Stores value of current string pointed by DE register into address pointed by HL @@ -1767,5 +1713,5 @@ __STORE_STR: pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret pop namespace -#line 49 "param1.bas" +#line 49 "zx48k/param1.bas" END diff --git a/tests/functional/zx48k/param2.asm b/tests/functional/zx48k/param2.asm index 54aaa431e..84107c2d8 100644 --- a/tests/functional/zx48k/param2.asm +++ b/tests/functional/zx48k/param2.asm @@ -345,7 +345,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 55 "param2.bas" +#line 55 "zx48k/param2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -576,94 +576,55 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 56 "param2.bas" +#line 56 "zx48k/param2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -672,7 +633,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -689,22 +736,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -738,7 +773,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -778,7 +813,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -815,7 +850,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -852,7 +887,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -945,7 +980,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -973,7 +1008,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1001,7 +1036,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1031,67 +1066,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1100,68 +1075,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1170,7 +1138,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1185,71 +1153,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1282,109 +1243,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1392,10 +1346,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1419,6 +1375,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1426,20 +1388,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1460,28 +1413,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1509,7 +1455,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 57 "param2.bas" +#line 57 "zx48k/param2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1553,7 +1499,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 58 "param2.bas" +#line 58 "zx48k/param2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string @@ -1666,5 +1612,5 @@ __STRCATEND: ret ENDP pop namespace -#line 59 "param2.bas" +#line 59 "zx48k/param2.bas" END diff --git a/tests/functional/zx48k/parambyref1.asm b/tests/functional/zx48k/parambyref1.asm index 3f4da7167..3bc07fed5 100644 --- a/tests/functional/zx48k/parambyref1.asm +++ b/tests/functional/zx48k/parambyref1.asm @@ -78,77 +78,40 @@ _test__leave: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -183,22 +146,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -207,7 +168,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -224,22 +271,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -273,7 +308,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -313,7 +348,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -350,7 +385,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -387,7 +422,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -480,7 +515,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -508,7 +543,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -536,7 +571,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -566,67 +601,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -635,68 +610,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -705,7 +673,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -720,71 +688,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -817,109 +778,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -927,10 +881,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -954,6 +910,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -961,20 +923,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -995,28 +948,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1044,7 +990,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 58 "parambyref1.bas" +#line 58 "zx48k/parambyref1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1065,7 +1011,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1192,5 +1138,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 59 "parambyref1.bas" +#line 59 "zx48k/parambyref1.bas" END diff --git a/tests/functional/zx48k/plot.asm b/tests/functional/zx48k/plot.asm index 5bb3fd02d..a03cf091e 100644 --- a/tests/functional/zx48k/plot.asm +++ b/tests/functional/zx48k/plot.asm @@ -169,7 +169,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 49 "plot.bas" +#line 49 "zx48k/plot.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" ; MIXED __FASTCAL__ / __CALLE__ PLOT Function ; Plots a point into the screen calling the ZX ROM PLOT routine @@ -212,125 +212,51 @@ __STOP: #line 8 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" - push namespace core -__IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret - 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address + ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address add hl, de ; Return current screen address in HL ret @@ -341,10 +267,11 @@ 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 - call __ATTR_ADDR __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 @@ -357,6 +284,73 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address ld (hl), a ; Store result in screen ret ENDP + pop namespace +#line 3 "/zxbasic/src/arch/zx48k/library-asm/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 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core +__IN_SCREEN: + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits + 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm" + push namespace core ; Sets the attribute at a given screen pixel address in hl ; HL contains the address in RAM for a given pixel (not a coordinate) SET_PIXEL_ADDR_ATTR: @@ -366,12 +360,11 @@ SET_PIXEL_ADDR_ATTR: rrca rrca and 3 - or 18h ld h, a - ld de, (SCREEN_ADDR) + ld de, (SCREEN_ATTR_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 - pop namespace + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" push namespace core PLOT: @@ -429,5 +422,5 @@ __PLOT_ERR: COORDS EQU 5C7Dh ENDP pop namespace -#line 50 "plot.bas" +#line 50 "zx48k/plot.bas" END diff --git a/tests/functional/zx48k/print.asm b/tests/functional/zx48k/print.asm index 40403fb1c..eec902f09 100644 --- a/tests/functional/zx48k/print.asm +++ b/tests/functional/zx48k/print.asm @@ -78,77 +78,40 @@ _a: DEFB 33h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -183,22 +146,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -207,7 +168,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -224,22 +271,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -273,7 +308,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -313,7 +348,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -350,7 +385,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -387,7 +422,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -480,7 +515,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -508,7 +543,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -536,7 +571,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -566,67 +601,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -635,68 +610,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -705,7 +673,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -720,71 +688,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -817,109 +778,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -927,10 +881,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -954,6 +910,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -961,20 +923,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -995,28 +948,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1044,7 +990,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 51 "print.bas" +#line 51 "zx48k/print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes @@ -1053,7 +999,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 52 "print.bas" +#line 52 "zx48k/print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1435,7 +1381,7 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH RECLAIM2 EQU 19E8h ENDP pop namespace -#line 53 "print.bas" +#line 53 "zx48k/print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" push namespace core @@ -1455,7 +1401,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1653,7 +1599,7 @@ __PRINT_FIX_LOOP: jp __PRINT_FIX_LOOP ENDP pop namespace -#line 54 "print.bas" +#line 54 "zx48k/print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" ; -------------------------------- @@ -1749,11 +1695,11 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 56 "print.bas" +#line 56 "zx48k/print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 58 "print.bas" +#line 58 "zx48k/print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 59 "print.bas" +#line 59 "zx48k/print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -2024,5 +1970,5 @@ __STRCATEND: ret ENDP pop namespace -#line 60 "print.bas" +#line 60 "zx48k/print.bas" END diff --git a/tests/functional/zx48k/print_arrstr.asm b/tests/functional/zx48k/print_arrstr.asm index 8cb0d7e45..fdbcc917f 100644 --- a/tests/functional/zx48k/print_arrstr.asm +++ b/tests/functional/zx48k/print_arrstr.asm @@ -430,94 +430,55 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 38 "print_arrstr.bas" +#line 38 "zx48k/print_arrstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; vim:ts=4:sw=4:et: ; PRINT command routine ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -526,7 +487,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -543,22 +590,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -592,7 +627,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -632,7 +667,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -669,7 +704,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -706,7 +741,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -799,7 +834,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -827,7 +862,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -855,7 +890,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -885,67 +920,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -954,68 +929,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1024,7 +992,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1039,71 +1007,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1136,109 +1097,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1246,10 +1200,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1273,6 +1229,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1280,20 +1242,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1314,28 +1267,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1363,7 +1309,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 39 "print_arrstr.bas" +#line 39 "zx48k/print_arrstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1566,7 +1512,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 40 "print_arrstr.bas" +#line 40 "zx48k/print_arrstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 ; Stores value of current string pointed by DE register into address pointed by HL @@ -1815,5 +1761,5 @@ __STORE_STR: pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret pop namespace -#line 41 "print_arrstr.bas" +#line 41 "zx48k/print_arrstr.bas" END diff --git a/tests/functional/zx48k/print_at.asm b/tests/functional/zx48k/print_at.asm index e919a8d7f..745b29a44 100644 --- a/tests/functional/zx48k/print_at.asm +++ b/tests/functional/zx48k/print_at.asm @@ -52,77 +52,40 @@ DEFB 20h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -157,22 +120,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -181,7 +142,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -198,22 +245,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -247,7 +282,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -287,7 +322,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -324,7 +359,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -361,7 +396,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -454,7 +489,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -482,7 +517,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -510,7 +545,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -540,67 +575,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -609,68 +584,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -679,7 +647,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -694,71 +662,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -791,109 +752,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -901,10 +855,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -928,6 +884,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -935,20 +897,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -969,28 +922,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1018,7 +964,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 27 "print_at.bas" +#line 27 "zx48k/print_at.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1329,5 +1275,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 28 "print_at.bas" +#line 28 "zx48k/print_at.bas" END diff --git a/tests/functional/zx48k/print_comma.asm b/tests/functional/zx48k/print_comma.asm index b312cb006..e9f54466c 100644 --- a/tests/functional/zx48k/print_comma.asm +++ b/tests/functional/zx48k/print_comma.asm @@ -43,77 +43,40 @@ ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -148,22 +111,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -172,7 +133,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -189,22 +236,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -238,7 +273,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -278,7 +313,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -315,7 +350,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -352,7 +387,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -445,7 +480,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -473,7 +508,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -501,7 +536,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -531,67 +566,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -600,68 +575,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -670,7 +638,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -685,71 +653,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -782,109 +743,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -892,10 +846,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -919,6 +875,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -926,20 +888,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -960,28 +913,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1009,7 +955,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 23 "print_comma.bas" +#line 23 "zx48k/print_comma.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1030,7 +976,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1131,5 +1077,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 24 "print_comma.bas" +#line 24 "zx48k/print_comma.bas" END diff --git a/tests/functional/zx48k/print_eol.asm b/tests/functional/zx48k/print_eol.asm index a722ecd60..86ce676a4 100644 --- a/tests/functional/zx48k/print_eol.asm +++ b/tests/functional/zx48k/print_eol.asm @@ -38,77 +38,40 @@ ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -143,22 +106,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -167,7 +128,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -184,22 +231,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -233,7 +268,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -273,7 +308,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -310,7 +345,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -347,7 +382,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -440,7 +475,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -468,7 +503,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -496,7 +531,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -526,67 +561,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -595,68 +570,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -665,7 +633,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -680,71 +648,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -777,109 +738,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -887,10 +841,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -914,6 +870,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -921,20 +883,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -955,28 +908,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1004,5 +950,5 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 18 "print_eol.bas" +#line 18 "zx48k/print_eol.bas" END diff --git a/tests/functional/zx48k/print_eol_attr.asm b/tests/functional/zx48k/print_eol_attr.asm index e223e8582..3aa885530 100644 --- a/tests/functional/zx48k/print_eol_attr.asm +++ b/tests/functional/zx48k/print_eol_attr.asm @@ -51,77 +51,40 @@ _a: ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -156,22 +119,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -180,7 +141,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -197,22 +244,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -246,7 +281,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -286,7 +321,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -323,7 +358,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -360,7 +395,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -453,7 +488,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -481,7 +516,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -509,7 +544,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -539,67 +574,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -608,68 +583,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -678,7 +646,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -693,71 +661,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -790,109 +751,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -900,10 +854,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -927,6 +883,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -934,20 +896,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -968,28 +921,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1023,7 +969,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 21 "print_eol_attr.bas" +#line 21 "zx48k/print_eol_attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1334,5 +1280,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 22 "print_eol_attr.bas" +#line 22 "zx48k/print_eol_attr.bas" END diff --git a/tests/functional/zx48k/print_f.asm b/tests/functional/zx48k/print_f.asm index feeeae02c..5f06b1045 100644 --- a/tests/functional/zx48k/print_f.asm +++ b/tests/functional/zx48k/print_f.asm @@ -50,77 +50,40 @@ _a: #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -155,22 +118,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -179,7 +140,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -196,22 +243,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -245,7 +280,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -285,7 +320,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -322,7 +357,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -359,7 +394,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -452,7 +487,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -480,7 +515,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -508,7 +543,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -538,67 +573,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -607,68 +582,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -677,7 +645,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -692,71 +660,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -789,109 +750,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -899,10 +853,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -926,6 +882,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -933,20 +895,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -967,28 +920,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1396,5 +1342,5 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH RECLAIM2 EQU 19E8h ENDP pop namespace -#line 21 "print_f.bas" +#line 21 "zx48k/print_f.bas" END diff --git a/tests/functional/zx48k/print_f16.asm b/tests/functional/zx48k/print_f16.asm index 93a5c3795..4a3ce9f37 100644 --- a/tests/functional/zx48k/print_f16.asm +++ b/tests/functional/zx48k/print_f16.asm @@ -44,77 +44,40 @@ _a: #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -149,22 +112,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -173,7 +134,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -190,22 +237,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -239,7 +274,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -279,7 +314,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -316,7 +351,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -353,7 +388,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -446,7 +481,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -474,7 +509,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -502,7 +537,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -532,67 +567,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -601,68 +576,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -671,7 +639,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -686,71 +654,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -783,109 +744,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -893,10 +847,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -920,6 +876,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -927,20 +889,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -961,28 +914,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1028,7 +974,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1226,5 +1172,5 @@ __PRINT_FIX_LOOP: jp __PRINT_FIX_LOOP ENDP pop namespace -#line 20 "print_f16.bas" +#line 20 "zx48k/print_f16.bas" END diff --git a/tests/functional/zx48k/print_i16.asm b/tests/functional/zx48k/print_i16.asm index eeb842e25..8c48a5d27 100644 --- a/tests/functional/zx48k/print_i16.asm +++ b/tests/functional/zx48k/print_i16.asm @@ -43,77 +43,40 @@ _a: #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -148,22 +111,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -172,7 +133,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -189,22 +236,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -238,7 +273,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -278,7 +313,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -315,7 +350,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -352,7 +387,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -445,7 +480,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -473,7 +508,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -501,7 +536,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -531,67 +566,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -600,68 +575,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -670,7 +638,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -685,71 +653,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -782,109 +743,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -892,10 +846,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -919,6 +875,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -926,20 +888,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -960,28 +913,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1027,7 +973,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1153,5 +1099,5 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 19 "print_i16.bas" +#line 19 "zx48k/print_i16.bas" END diff --git a/tests/functional/zx48k/print_i32.asm b/tests/functional/zx48k/print_i32.asm index 85e3cbed4..48ec80271 100644 --- a/tests/functional/zx48k/print_i32.asm +++ b/tests/functional/zx48k/print_i32.asm @@ -44,77 +44,40 @@ _a: #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -149,22 +112,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -173,7 +134,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -190,22 +237,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -239,7 +274,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -279,7 +314,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -316,7 +351,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -353,7 +388,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -446,7 +481,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -474,7 +509,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -502,7 +537,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -532,67 +567,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -601,68 +576,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -671,7 +639,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -686,71 +654,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -783,109 +744,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -893,10 +847,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -920,6 +876,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -927,20 +889,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -961,28 +914,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1028,7 +974,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1207,5 +1153,5 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 20 "print_i32.bas" +#line 20 "zx48k/print_i32.bas" END diff --git a/tests/functional/zx48k/print_i8.asm b/tests/functional/zx48k/print_i8.asm index 3dce7658e..9ea46a018 100644 --- a/tests/functional/zx48k/print_i8.asm +++ b/tests/functional/zx48k/print_i8.asm @@ -43,77 +43,40 @@ _a: #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -148,22 +111,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -172,7 +133,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -189,22 +236,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -238,7 +273,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -278,7 +313,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -315,7 +350,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -352,7 +387,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -445,7 +480,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -473,7 +508,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -501,7 +536,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -531,67 +566,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -600,68 +575,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -670,7 +638,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -685,71 +653,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -782,109 +743,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -892,10 +846,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -919,6 +875,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -926,20 +888,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -960,28 +913,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1027,7 +973,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1127,5 +1073,5 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 19 "print_i8.bas" +#line 19 "zx48k/print_i8.bas" END diff --git a/tests/functional/zx48k/print_tab.asm b/tests/functional/zx48k/print_tab.asm index 3de800dbb..b250d65a6 100644 --- a/tests/functional/zx48k/print_tab.asm +++ b/tests/functional/zx48k/print_tab.asm @@ -39,77 +39,40 @@ ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -144,22 +107,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -168,7 +129,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -185,22 +232,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -234,7 +269,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -274,7 +309,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -311,7 +346,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -348,7 +383,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -441,7 +476,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -469,7 +504,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -497,7 +532,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -527,67 +562,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -596,68 +571,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -666,7 +634,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -681,71 +649,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -778,109 +739,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -888,10 +842,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -915,6 +871,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -922,20 +884,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -956,28 +909,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1005,5 +951,5 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 19 "print_tab.bas" +#line 19 "zx48k/print_tab.bas" END diff --git a/tests/functional/zx48k/print_u16.asm b/tests/functional/zx48k/print_u16.asm index adc130e52..c4f55e5d8 100644 --- a/tests/functional/zx48k/print_u16.asm +++ b/tests/functional/zx48k/print_u16.asm @@ -44,77 +44,40 @@ _a: #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -149,22 +112,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -173,7 +134,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -190,22 +237,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -239,7 +274,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -279,7 +314,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -316,7 +351,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -353,7 +388,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -446,7 +481,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -474,7 +509,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -502,7 +537,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -532,67 +567,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -601,68 +576,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -671,7 +639,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -686,71 +654,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -783,109 +744,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -893,10 +847,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -920,6 +876,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -927,20 +889,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -961,28 +914,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1028,7 +974,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1155,5 +1101,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 19 "print_u16.bas" +#line 19 "zx48k/print_u16.bas" END diff --git a/tests/functional/zx48k/print_u32.asm b/tests/functional/zx48k/print_u32.asm index bf44550af..3855506b0 100644 --- a/tests/functional/zx48k/print_u32.asm +++ b/tests/functional/zx48k/print_u32.asm @@ -45,77 +45,40 @@ _a: #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -150,22 +113,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -174,7 +135,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -191,22 +238,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -240,7 +275,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -280,7 +315,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -317,7 +352,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -354,7 +389,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -447,7 +482,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -475,7 +510,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -503,7 +538,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -533,67 +568,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -602,68 +577,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -672,7 +640,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -687,71 +655,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -784,109 +745,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -894,10 +848,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -921,6 +877,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -928,20 +890,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -962,28 +915,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1029,7 +975,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1209,5 +1155,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" -#line 20 "print_u32.bas" +#line 20 "zx48k/print_u32.bas" END diff --git a/tests/functional/zx48k/print_u8.asm b/tests/functional/zx48k/print_u8.asm index b667ce4ce..a985991a1 100644 --- a/tests/functional/zx48k/print_u8.asm +++ b/tests/functional/zx48k/print_u8.asm @@ -44,77 +44,40 @@ _a: #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -149,22 +112,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -173,7 +134,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -190,22 +237,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -239,7 +274,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -279,7 +314,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -316,7 +351,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -353,7 +388,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -446,7 +481,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -474,7 +509,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -502,7 +537,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -532,67 +567,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -601,68 +576,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -671,7 +639,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -686,71 +654,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -783,109 +744,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -893,10 +847,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -920,6 +876,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -927,20 +889,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -961,28 +914,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1028,7 +974,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1129,5 +1075,5 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 19 "print_u8.bas" +#line 19 "zx48k/print_u8.bas" END diff --git a/tests/functional/zx48k/read10.asm b/tests/functional/zx48k/read10.asm index a8747fe4b..7fd7342e3 100644 --- a/tests/functional/zx48k/read10.asm +++ b/tests/functional/zx48k/read10.asm @@ -203,7 +203,7 @@ __MULF: ; Multiplication defb 38h; ; END CALC jp __FPSTACK_POP pop namespace -#line 115 "read10.bas" +#line 115 "zx48k/read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load ; A => Offset @@ -244,7 +244,7 @@ __PLOADF: add hl, de jp __LOADF pop namespace -#line 116 "read10.bas" +#line 116 "zx48k/read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -270,79 +270,42 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace -#line 117 "read10.bas" +#line 117 "zx48k/read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -377,22 +340,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -401,7 +362,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -418,22 +465,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -467,7 +502,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -507,7 +542,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -544,7 +579,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -581,7 +616,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -674,7 +709,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -702,7 +737,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -730,7 +765,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -760,67 +795,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -829,68 +804,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -899,7 +867,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -914,71 +882,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1011,109 +972,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1121,10 +1075,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1148,6 +1104,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1155,20 +1117,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1189,28 +1142,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1238,7 +1184,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 118 "read10.bas" +#line 118 "zx48k/read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1580,7 +1526,7 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH RECLAIM2 EQU 19E8h ENDP pop namespace -#line 119 "read10.bas" +#line 119 "zx48k/read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stores FP number in A ED CB at location HL+IX ; HL = Offset @@ -1626,7 +1572,7 @@ __PSTOREF: pop de jp __STOREF pop namespace -#line 120 "read10.bas" +#line 120 "zx48k/read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2386,7 +2332,7 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 121 "read10.bas" +#line 121 "zx48k/read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" push namespace core SIN: ; Computes SIN using ROM FP-CALC @@ -2396,7 +2342,7 @@ SIN: ; Computes SIN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 122 "read10.bas" +#line 122 "zx48k/read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" push namespace core TAN: ; Computes TAN using ROM FP-CALC @@ -2406,5 +2352,5 @@ TAN: ; Computes TAN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 123 "read10.bas" +#line 123 "zx48k/read10.bas" END diff --git a/tests/functional/zx48k/read12.asm b/tests/functional/zx48k/read12.asm index 7afe3002f..3d3eff8bf 100644 --- a/tests/functional/zx48k/read12.asm +++ b/tests/functional/zx48k/read12.asm @@ -415,94 +415,55 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 51 "read12.bas" +#line 51 "zx48k/read12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -511,7 +472,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -528,22 +575,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -577,7 +612,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -617,7 +652,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -654,7 +689,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -691,7 +726,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -784,7 +819,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -812,7 +847,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -840,7 +875,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -870,67 +905,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -939,68 +914,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1009,7 +977,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1024,71 +992,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1121,109 +1082,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1231,10 +1185,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1258,6 +1214,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1265,20 +1227,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1299,28 +1252,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1348,7 +1294,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 52 "read12.bas" +#line 52 "zx48k/read12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" push namespace core @@ -1368,7 +1314,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1468,7 +1414,7 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 53 "read12.bas" +#line 53 "zx48k/read12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2219,5 +2165,5 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 54 "read12.bas" +#line 54 "zx48k/read12.bas" END diff --git a/tests/functional/zx48k/read13.asm b/tests/functional/zx48k/read13.asm index 3b8cbe93f..be7b848c9 100644 --- a/tests/functional/zx48k/read13.asm +++ b/tests/functional/zx48k/read13.asm @@ -297,7 +297,7 @@ TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables ENDP pop namespace -#line 110 "read13.bas" +#line 110 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -430,7 +430,7 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) jp __U32TOFREG_LOOP ; Proceed as an integer ENDP pop namespace -#line 111 "read13.bas" +#line 111 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL @@ -449,7 +449,7 @@ __ILOAD32: ex de, hl ret pop namespace -#line 112 "read13.bas" +#line 112 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- @@ -508,7 +508,7 @@ __MULF: ; Multiplication defb 38h; ; END CALC jp __FPSTACK_POP pop namespace -#line 113 "read13.bas" +#line 113 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" ; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223 @@ -604,7 +604,7 @@ __ROUND_FIX: ; rounds a 64bit (32.32) fixed point number to 16.16 jp m, __NEG32 ; if negative, negates it ret pop namespace -#line 114 "read13.bas" +#line 114 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -630,79 +630,42 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace -#line 115 "read13.bas" +#line 115 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -737,22 +700,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -761,7 +722,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -778,22 +825,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -827,7 +862,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -867,7 +902,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -904,7 +939,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -941,7 +976,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -1034,7 +1069,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -1062,7 +1097,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1090,7 +1125,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1120,67 +1155,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1189,68 +1164,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1259,7 +1227,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1274,71 +1242,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1371,109 +1332,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1481,10 +1435,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1508,6 +1464,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1515,20 +1477,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1549,28 +1502,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1598,7 +1544,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 116 "read13.bas" +#line 116 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" push namespace core @@ -1618,7 +1564,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1790,7 +1736,7 @@ __PRINT_FIX_LOOP: jp __PRINT_FIX_LOOP ENDP pop namespace -#line 117 "read13.bas" +#line 117 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2693,7 +2639,7 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 118 "read13.bas" +#line 118 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" push namespace core SIN: ; Computes SIN using ROM FP-CALC @@ -2703,7 +2649,7 @@ SIN: ; Computes SIN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 119 "read13.bas" +#line 119 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/store32.asm" push namespace core __PISTORE32: @@ -2727,7 +2673,7 @@ __STORE32: ; Stores the given integer in DEBC at address HL ld (hl), d ret pop namespace -#line 120 "read13.bas" +#line 120 "zx48k/read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" push namespace core TAN: ; Computes TAN using ROM FP-CALC @@ -2737,5 +2683,5 @@ TAN: ; Computes TAN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 121 "read13.bas" +#line 121 "zx48k/read13.bas" END diff --git a/tests/functional/zx48k/read5.asm b/tests/functional/zx48k/read5.asm index 8e52303c3..555da465a 100644 --- a/tests/functional/zx48k/read5.asm +++ b/tests/functional/zx48k/read5.asm @@ -203,7 +203,7 @@ __MULF: ; Multiplication defb 38h; ; END CALC jp __FPSTACK_POP pop namespace -#line 109 "read5.bas" +#line 109 "zx48k/read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -229,79 +229,42 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace -#line 110 "read5.bas" +#line 110 "zx48k/read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -336,22 +299,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -360,7 +321,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -377,22 +424,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -426,7 +461,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -466,7 +501,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -503,7 +538,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -540,7 +575,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -633,7 +668,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -661,7 +696,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -689,7 +724,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -719,67 +754,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -788,68 +763,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -858,7 +826,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -873,71 +841,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -970,109 +931,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1080,10 +1034,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1107,6 +1063,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1114,20 +1076,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1148,28 +1101,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1197,7 +1143,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 111 "read5.bas" +#line 111 "zx48k/read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1539,7 +1485,7 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH RECLAIM2 EQU 19E8h ENDP pop namespace -#line 112 "read5.bas" +#line 112 "zx48k/read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2327,7 +2273,7 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 113 "read5.bas" +#line 113 "zx48k/read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" push namespace core SIN: ; Computes SIN using ROM FP-CALC @@ -2337,7 +2283,7 @@ SIN: ; Computes SIN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 114 "read5.bas" +#line 114 "zx48k/read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) @@ -2366,7 +2312,7 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 115 "read5.bas" +#line 115 "zx48k/read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" push namespace core TAN: ; Computes TAN using ROM FP-CALC @@ -2376,5 +2322,5 @@ TAN: ; Computes TAN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 116 "read5.bas" +#line 116 "zx48k/read5.bas" END diff --git a/tests/functional/zx48k/read8.asm b/tests/functional/zx48k/read8.asm index 9718cbdf4..6fb3fd9a1 100644 --- a/tests/functional/zx48k/read8.asm +++ b/tests/functional/zx48k/read8.asm @@ -218,7 +218,7 @@ __MULF: ; Multiplication defb 38h; ; END CALC jp __FPSTACK_POP pop namespace -#line 100 "read8.bas" +#line 100 "zx48k/read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -244,79 +244,42 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace -#line 101 "read8.bas" +#line 101 "zx48k/read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -351,22 +314,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -375,7 +336,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -392,22 +439,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -441,7 +476,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -481,7 +516,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -518,7 +553,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -555,7 +590,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -648,7 +683,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -676,7 +711,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -704,7 +739,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -734,67 +769,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -803,68 +778,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -873,7 +841,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -888,71 +856,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -985,109 +946,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1095,10 +1049,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1122,6 +1078,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1129,20 +1091,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1163,28 +1116,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1212,7 +1158,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 102 "read8.bas" +#line 102 "zx48k/read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1554,7 +1500,7 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH RECLAIM2 EQU 19E8h ENDP pop namespace -#line 103 "read8.bas" +#line 103 "zx48k/read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2342,7 +2288,7 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 104 "read8.bas" +#line 104 "zx48k/read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" push namespace core SIN: ; Computes SIN using ROM FP-CALC @@ -2352,7 +2298,7 @@ SIN: ; Computes SIN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 105 "read8.bas" +#line 105 "zx48k/read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) @@ -2381,7 +2327,7 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 106 "read8.bas" +#line 106 "zx48k/read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" push namespace core TAN: ; Computes TAN using ROM FP-CALC @@ -2391,5 +2337,5 @@ TAN: ; Computes TAN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 107 "read8.bas" +#line 107 "zx48k/read8.bas" END diff --git a/tests/functional/zx48k/read9.asm b/tests/functional/zx48k/read9.asm index 15a3678df..282f54cd9 100644 --- a/tests/functional/zx48k/read9.asm +++ b/tests/functional/zx48k/read9.asm @@ -307,7 +307,7 @@ TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables ENDP pop namespace -#line 115 "read9.bas" +#line 115 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB @@ -335,7 +335,7 @@ __LOADF: ; Loads a 40 bits FP number from address pointed by HL ld b, (hl) ret pop namespace -#line 116 "read9.bas" +#line 116 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- @@ -394,7 +394,7 @@ __MULF: ; Multiplication defb 38h; ; END CALC jp __FPSTACK_POP pop namespace -#line 117 "read9.bas" +#line 117 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -420,79 +420,42 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace -#line 118 "read9.bas" +#line 118 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -527,22 +490,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -551,7 +512,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -568,22 +615,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -617,7 +652,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -657,7 +692,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -694,7 +729,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -731,7 +766,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -824,7 +859,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -852,7 +887,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -880,7 +915,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -910,67 +945,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -979,68 +954,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1049,7 +1017,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1064,71 +1032,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1161,109 +1122,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1271,10 +1225,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1298,6 +1254,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1305,20 +1267,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1339,28 +1292,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1388,7 +1334,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 119 "read9.bas" +#line 119 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1730,7 +1676,7 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH RECLAIM2 EQU 19E8h ENDP pop namespace -#line 120 "read9.bas" +#line 120 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2490,7 +2436,7 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 121 "read9.bas" +#line 121 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" push namespace core SIN: ; Computes SIN using ROM FP-CALC @@ -2500,7 +2446,7 @@ SIN: ; Computes SIN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 122 "read9.bas" +#line 122 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) @@ -2529,7 +2475,7 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 123 "read9.bas" +#line 123 "zx48k/read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" push namespace core TAN: ; Computes TAN using ROM FP-CALC @@ -2539,5 +2485,5 @@ TAN: ; Computes TAN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 124 "read9.bas" +#line 124 "zx48k/read9.bas" END diff --git a/tests/functional/zx48k/readokdown.asm b/tests/functional/zx48k/readokdown.asm index 544d55dc0..2fc6d4c2d 100644 --- a/tests/functional/zx48k/readokdown.asm +++ b/tests/functional/zx48k/readokdown.asm @@ -133,77 +133,40 @@ __DATA__END: DEFB 00h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -238,22 +201,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -262,7 +223,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -279,22 +326,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -328,7 +363,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -368,7 +403,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -405,7 +440,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -442,7 +477,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -535,7 +570,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -563,7 +598,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -591,7 +626,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -621,67 +656,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -690,68 +665,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -760,7 +728,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -775,71 +743,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -872,109 +833,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -982,10 +936,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1009,6 +965,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1016,20 +978,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1050,28 +1003,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1099,7 +1045,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 92 "readokdown.bas" +#line 92 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1481,7 +1427,7 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH RECLAIM2 EQU 19E8h ENDP pop namespace -#line 93 "readokdown.bas" +#line 93 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" push namespace core @@ -1501,7 +1447,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1699,7 +1645,7 @@ __PRINT_FIX_LOOP: jp __PRINT_FIX_LOOP ENDP pop namespace -#line 94 "readokdown.bas" +#line 94 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" ; --------------------------------------------------------- @@ -1848,7 +1794,7 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 96 "readokdown.bas" +#line 96 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" ; -------------------------------- @@ -1944,13 +1890,13 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 97 "readokdown.bas" +#line 97 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 98 "readokdown.bas" +#line 98 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" -#line 99 "readokdown.bas" +#line 99 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 100 "readokdown.bas" +#line 100 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2712,7 +2658,7 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 101 "readokdown.bas" +#line 101 "zx48k/readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) @@ -2741,5 +2687,5 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 102 "readokdown.bas" +#line 102 "zx48k/readokdown.bas" END diff --git a/tests/functional/zx48k/readokup.asm b/tests/functional/zx48k/readokup.asm index ef30377c6..abad69582 100644 --- a/tests/functional/zx48k/readokup.asm +++ b/tests/functional/zx48k/readokup.asm @@ -132,77 +132,40 @@ __DATA__END: DEFB 00h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -237,22 +200,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -261,7 +222,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -278,22 +325,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -327,7 +362,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -367,7 +402,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -404,7 +439,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -441,7 +476,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -534,7 +569,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -562,7 +597,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -590,7 +625,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -620,67 +655,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -689,68 +664,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -759,7 +727,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -774,71 +742,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -871,109 +832,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -981,10 +935,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1008,6 +964,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1015,20 +977,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1049,28 +1002,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1098,7 +1044,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 91 "readokup.bas" +#line 91 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1480,7 +1426,7 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH RECLAIM2 EQU 19E8h ENDP pop namespace -#line 92 "readokup.bas" +#line 92 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" push namespace core @@ -1500,7 +1446,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1698,7 +1644,7 @@ __PRINT_FIX_LOOP: jp __PRINT_FIX_LOOP ENDP pop namespace -#line 93 "readokup.bas" +#line 93 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" ; --------------------------------------------------------- @@ -1847,7 +1793,7 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 95 "readokup.bas" +#line 95 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" ; -------------------------------- @@ -1943,13 +1889,13 @@ __PRINTU_LOOP: jp __PRINTU_LOOP ; Uses JP in loops ENDP pop namespace -#line 96 "readokup.bas" +#line 96 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 97 "readokup.bas" +#line 97 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" -#line 98 "readokup.bas" +#line 98 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 99 "readokup.bas" +#line 99 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code @@ -2711,7 +2657,7 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 100 "readokup.bas" +#line 100 "zx48k/readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) @@ -2740,5 +2686,5 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 101 "readokup.bas" +#line 101 "zx48k/readokup.bas" END diff --git a/tests/functional/zx48k/simple.asm b/tests/functional/zx48k/simple.asm index dfec9824c..639ebd583 100644 --- a/tests/functional/zx48k/simple.asm +++ b/tests/functional/zx48k/simple.asm @@ -59,77 +59,40 @@ DEFB 44h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -164,22 +127,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -188,7 +149,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -205,22 +252,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -254,7 +289,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -294,7 +329,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -331,7 +366,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -368,7 +403,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -461,7 +496,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -489,7 +524,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -517,7 +552,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -547,67 +582,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -616,68 +591,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -686,7 +654,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -701,71 +669,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -798,109 +759,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -908,10 +862,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -935,6 +891,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -942,20 +904,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -976,28 +929,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1025,7 +971,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 34 "simple.bas" +#line 34 "zx48k/simple.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1336,5 +1282,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 35 "simple.bas" +#line 35 "zx48k/simple.bas" END diff --git a/tests/functional/zx48k/slice2.asm b/tests/functional/zx48k/slice2.asm index de97e10cb..7ec544afe 100644 --- a/tests/functional/zx48k/slice2.asm +++ b/tests/functional/zx48k/slice2.asm @@ -130,68 +130,60 @@ _doubleSizePrint__leave: DEFB 64h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation -#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + ;; Clears the user screen (24 rows) +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 4 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace #line 106 "zx48k/slice2.bas" diff --git a/tests/functional/zx48k/spfill.asm b/tests/functional/zx48k/spfill.asm index e34124420..e3a992698 100644 --- a/tests/functional/zx48k/spfill.asm +++ b/tests/functional/zx48k/spfill.asm @@ -720,125 +720,51 @@ __STOP: ; X in top of the stack #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" - push namespace core -__IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret - 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address + ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address add hl, de ; Return current screen address in HL ret @@ -849,10 +775,11 @@ 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 - call __ATTR_ADDR __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 @@ -865,6 +792,73 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address ld (hl), a ; Store result in screen ret ENDP + pop namespace +#line 3 "/zxbasic/src/arch/zx48k/library-asm/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 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core +__IN_SCREEN: + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits + 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 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/set_pixel_addr_attr.asm" + push namespace core ; Sets the attribute at a given screen pixel address in hl ; HL contains the address in RAM for a given pixel (not a coordinate) SET_PIXEL_ADDR_ATTR: @@ -874,12 +868,11 @@ SET_PIXEL_ADDR_ATTR: rrca rrca and 3 - or 18h ld h, a - ld de, (SCREEN_ADDR) + ld de, (SCREEN_ATTR_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 - pop namespace + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" push namespace core PLOT: @@ -1106,6 +1099,37 @@ __CIRCLE_PLOT: ENDP pop namespace #line 555 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + ;; Clears the user screen (24 rows) + push namespace core +CLS: + PROC + ld hl, 0 + ld (COORDS), hl + ld hl, SCR_SIZE + ld (S_POSN), hl + ld hl, (SCREEN_ADDR) + ld (DFCC), hl + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6143 + ldir + ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret + ENDP + pop namespace +#line 556 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pause.asm" ; The PAUSE statement (Calling the ROM) push namespace core diff --git a/tests/functional/zx48k/str0.asm b/tests/functional/zx48k/str0.asm index 468f03459..460fbd9ed 100644 --- a/tests/functional/zx48k/str0.asm +++ b/tests/functional/zx48k/str0.asm @@ -350,82 +350,45 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 58 "str0.bas" +#line 58 "zx48k/str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -460,22 +423,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -484,7 +445,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -501,22 +548,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -550,7 +585,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -590,7 +625,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -627,7 +662,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -664,7 +699,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -757,7 +792,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -785,7 +820,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -813,7 +848,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -843,67 +878,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -912,68 +887,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -982,7 +950,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -997,71 +965,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1094,109 +1055,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1204,10 +1158,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1231,6 +1187,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1238,20 +1200,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1272,28 +1225,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1327,7 +1273,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 59 "str0.bas" +#line 59 "zx48k/str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1371,7 +1317,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 60 "str0.bas" +#line 60 "zx48k/str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation ; Given a FP number in C ED LH @@ -1626,7 +1572,7 @@ __STR_END: STK_END EQU 5C65h ENDP pop namespace -#line 61 "str0.bas" +#line 61 "zx48k/str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string @@ -1739,7 +1685,7 @@ __STRCATEND: ret ENDP pop namespace -#line 62 "str0.bas" +#line 62 "zx48k/str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -1836,5 +1782,5 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 63 "str0.bas" +#line 63 "zx48k/str0.bas" END diff --git a/tests/functional/zx48k/str01.asm b/tests/functional/zx48k/str01.asm index b1e25df8b..5b8e05410 100644 --- a/tests/functional/zx48k/str01.asm +++ b/tests/functional/zx48k/str01.asm @@ -351,7 +351,7 @@ __STORE_STR2: dec hl ; HL points to mem address variable. This might be useful in the future. ret pop namespace -#line 24 "str01.bas" +#line 24 "zx48k/str01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation ; Given a FP number in C ED LH @@ -590,17 +590,32 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK jp __FPSTACK_PUSH pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 10 "/zxbasic/src/arch/zx48k/library-asm/str.asm" push namespace core __STR: @@ -653,7 +668,7 @@ __STR_END: STK_END EQU 5C65h ENDP pop namespace -#line 25 "str01.bas" +#line 25 "zx48k/str01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -750,5 +765,5 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 26 "str01.bas" +#line 26 "zx48k/str01.bas" END diff --git a/tests/functional/zx48k/str02.asm b/tests/functional/zx48k/str02.asm index 68bddbba9..690bcd52c 100644 --- a/tests/functional/zx48k/str02.asm +++ b/tests/functional/zx48k/str02.asm @@ -333,7 +333,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 39 "str02.bas" +#line 39 "zx48k/str02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when ; the value of B$ if already duplicated onto the stack. @@ -367,7 +367,7 @@ __STORE_STR2: dec hl ; HL points to mem address variable. This might be useful in the future. ret pop namespace -#line 40 "str02.bas" +#line 40 "zx48k/str02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation ; Given a FP number in C ED LH @@ -606,17 +606,32 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK jp __FPSTACK_PUSH pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 10 "/zxbasic/src/arch/zx48k/library-asm/str.asm" push namespace core __STR: @@ -669,7 +684,7 @@ __STR_END: STK_END EQU 5C65h ENDP pop namespace -#line 41 "str02.bas" +#line 41 "zx48k/str02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string @@ -782,7 +797,7 @@ __STRCATEND: ret ENDP pop namespace -#line 42 "str02.bas" +#line 42 "zx48k/str02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -879,5 +894,5 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 43 "str02.bas" +#line 43 "zx48k/str02.bas" END diff --git a/tests/functional/zx48k/strbase2.asm b/tests/functional/zx48k/strbase2.asm index cdf73bab3..f1e969318 100644 --- a/tests/functional/zx48k/strbase2.asm +++ b/tests/functional/zx48k/strbase2.asm @@ -473,82 +473,45 @@ __FREE_STR: ret ENDP pop namespace -#line 58 "strbase2.bas" +#line 58 "zx48k/strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -583,22 +546,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -607,7 +568,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -624,22 +671,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -673,7 +708,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -713,7 +748,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -750,7 +785,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -787,7 +822,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -880,7 +915,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -908,7 +943,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -936,7 +971,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -966,67 +1001,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1035,68 +1010,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1105,7 +1073,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1120,71 +1088,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1217,109 +1178,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1327,10 +1281,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1354,6 +1310,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1361,20 +1323,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1395,28 +1348,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1450,7 +1396,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 59 "strbase2.bas" +#line 59 "zx48k/strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1494,7 +1440,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 60 "strbase2.bas" +#line 60 "zx48k/strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 ; Stores value of current string pointed by DE register into address pointed by HL @@ -1901,7 +1847,7 @@ __STORE_STR: pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret pop namespace -#line 61 "strbase2.bas" +#line 61 "zx48k/strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when ; the value of B$ if already duplicated onto the stack. @@ -1935,7 +1881,7 @@ __STORE_STR2: dec hl ; HL points to mem address variable. This might be useful in the future. ret pop namespace -#line 62 "strbase2.bas" +#line 62 "zx48k/strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library ; HL = Str pointer @@ -2037,5 +1983,5 @@ __FREE_ON_EXIT: ret ENDP pop namespace -#line 63 "strbase2.bas" +#line 63 "zx48k/strbase2.bas" END diff --git a/tests/functional/zx48k/stringparam.asm b/tests/functional/zx48k/stringparam.asm index bcae04539..731a27c3d 100644 --- a/tests/functional/zx48k/stringparam.asm +++ b/tests/functional/zx48k/stringparam.asm @@ -342,7 +342,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 52 "stringparam.bas" +#line 52 "zx48k/stringparam.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -573,97 +573,58 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 53 "stringparam.bas" +#line 53 "zx48k/stringparam.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -672,7 +633,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -689,22 +736,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -738,7 +773,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -778,7 +813,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -815,7 +850,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -852,7 +887,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -945,7 +980,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -973,7 +1008,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1001,7 +1036,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1031,67 +1066,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1100,68 +1075,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1170,7 +1138,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1185,71 +1153,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1282,109 +1243,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1392,10 +1346,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1419,6 +1375,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1426,20 +1388,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1460,28 +1413,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1515,7 +1461,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 54 "stringparam.bas" +#line 54 "zx48k/stringparam.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1559,5 +1505,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 55 "stringparam.bas" +#line 55 "zx48k/stringparam.bas" END diff --git a/tests/functional/zx48k/strlocal0.asm b/tests/functional/zx48k/strlocal0.asm index 5ffeb92d9..33840e368 100644 --- a/tests/functional/zx48k/strlocal0.asm +++ b/tests/functional/zx48k/strlocal0.asm @@ -346,82 +346,45 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 56 "strlocal0.bas" +#line 56 "zx48k/strlocal0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -456,22 +419,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -480,7 +441,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -497,22 +544,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -546,7 +581,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -586,7 +621,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -623,7 +658,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -660,7 +695,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -753,7 +788,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -781,7 +816,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -809,7 +844,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -839,67 +874,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -908,68 +883,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -978,7 +946,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -993,71 +961,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1090,109 +1051,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1200,10 +1154,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1227,6 +1183,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1234,20 +1196,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1268,28 +1221,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1323,7 +1269,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 57 "strlocal0.bas" +#line 57 "zx48k/strlocal0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1367,7 +1313,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 58 "strlocal0.bas" +#line 58 "zx48k/strlocal0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 ; @@ -1788,5 +1734,5 @@ __PSTORE_STR: add hl, bc jp __STORE_STR pop namespace -#line 59 "strlocal0.bas" +#line 59 "zx48k/strlocal0.bas" END diff --git a/tests/functional/zx48k/strparam0.asm b/tests/functional/zx48k/strparam0.asm index 9ea8b7970..e7289f5b3 100644 --- a/tests/functional/zx48k/strparam0.asm +++ b/tests/functional/zx48k/strparam0.asm @@ -372,7 +372,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 82 "strparam0.bas" +#line 82 "zx48k/strparam0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -603,97 +603,58 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 83 "strparam0.bas" +#line 83 "zx48k/strparam0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -702,7 +663,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -719,22 +766,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -768,7 +803,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -808,7 +843,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -845,7 +880,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -882,7 +917,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -975,7 +1010,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -1003,7 +1038,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1031,7 +1066,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1061,67 +1096,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1130,68 +1105,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1200,7 +1168,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1215,71 +1183,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1312,109 +1273,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1422,10 +1376,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1449,6 +1405,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1456,20 +1418,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1490,28 +1443,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1545,7 +1491,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 84 "strparam0.bas" +#line 84 "zx48k/strparam0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1589,5 +1535,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 85 "strparam0.bas" +#line 85 "zx48k/strparam0.bas" END diff --git a/tests/functional/zx48k/strparam1.asm b/tests/functional/zx48k/strparam1.asm index e23fd6c5e..b04f590b5 100644 --- a/tests/functional/zx48k/strparam1.asm +++ b/tests/functional/zx48k/strparam1.asm @@ -358,7 +358,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 67 "strparam1.bas" +#line 67 "zx48k/strparam1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 ; @@ -814,7 +814,7 @@ __PSTORE_STR: add hl, bc jp __STORE_STR pop namespace -#line 68 "strparam1.bas" +#line 68 "zx48k/strparam1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation ; Given a FP number in C ED LH @@ -860,17 +860,32 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK jp __FPSTACK_PUSH pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 10 "/zxbasic/src/arch/zx48k/library-asm/str.asm" push namespace core __STR: @@ -923,7 +938,7 @@ __STR_END: STK_END EQU 5C65h ENDP pop namespace -#line 69 "strparam1.bas" +#line 69 "zx48k/strparam1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string @@ -1036,7 +1051,7 @@ __STRCATEND: ret ENDP pop namespace -#line 70 "strparam1.bas" +#line 70 "zx48k/strparam1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" push namespace core @@ -1133,5 +1148,5 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 71 "strparam1.bas" +#line 71 "zx48k/strparam1.bas" END diff --git a/tests/functional/zx48k/strparam2.asm b/tests/functional/zx48k/strparam2.asm index 724818869..4d64d0f2d 100644 --- a/tests/functional/zx48k/strparam2.asm +++ b/tests/functional/zx48k/strparam2.asm @@ -99,77 +99,40 @@ _test__leave: ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -204,22 +167,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -228,7 +189,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -245,22 +292,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -294,7 +329,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -334,7 +369,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -371,7 +406,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -408,7 +443,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -501,7 +536,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -529,7 +564,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -557,7 +592,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -587,67 +622,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -656,68 +631,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -726,7 +694,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -741,71 +709,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -838,109 +799,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -948,10 +902,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -975,6 +931,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -982,20 +944,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1016,28 +969,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1071,7 +1017,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 69 "strparam2.bas" +#line 69 "zx48k/strparam2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1382,7 +1328,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 70 "strparam2.bas" +#line 70 "zx48k/strparam2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 ; Stores value of current string pointed by DE register into address pointed by HL @@ -1789,5 +1735,5 @@ __STORE_STR: pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret pop namespace -#line 71 "strparam2.bas" +#line 71 "zx48k/strparam2.bas" END diff --git a/tests/functional/zx48k/strparam3.asm b/tests/functional/zx48k/strparam3.asm index e916f2973..5b10b8c44 100644 --- a/tests/functional/zx48k/strparam3.asm +++ b/tests/functional/zx48k/strparam3.asm @@ -366,7 +366,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ret ENDP pop namespace -#line 76 "strparam3.bas" +#line 76 "zx48k/strparam3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -597,97 +597,58 @@ __LOADSTR: ; __FASTCALL__ entry pop hl ; Recovers destiny in hl as result ret pop namespace -#line 77 "strparam3.bas" +#line 77 "zx48k/strparam3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -696,7 +657,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -713,22 +760,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -762,7 +797,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -802,7 +837,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -839,7 +874,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -876,7 +911,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -969,7 +1004,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -997,7 +1032,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -1025,7 +1060,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -1055,67 +1090,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -1124,68 +1099,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -1194,7 +1162,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -1209,71 +1177,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -1306,109 +1267,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1416,10 +1370,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1443,6 +1399,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1450,20 +1412,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1484,28 +1437,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1539,7 +1485,7 @@ PRINT_EOL_ATTR: call PRINT_EOL jp COPY_ATTR pop namespace -#line 78 "strparam3.bas" +#line 78 "zx48k/strparam3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL @@ -1583,5 +1529,5 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 79 "strparam3.bas" +#line 79 "zx48k/strparam3.bas" END diff --git a/tests/functional/zx48k/subrec.asm b/tests/functional/zx48k/subrec.asm index cfcb3f0d0..f2dcaaae4 100644 --- a/tests/functional/zx48k/subrec.asm +++ b/tests/functional/zx48k/subrec.asm @@ -148,71 +148,63 @@ _fact__leave: DEFB 20h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation -#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + ;; Clears the user screen (24 rows) +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 4 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace -#line 116 "subrec.bas" +#line 116 "zx48k/subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" ; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223 @@ -295,13 +287,15 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) ld l, c ret pop namespace -#line 117 "subrec.bas" +#line 117 "zx48k/subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -336,22 +330,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -360,7 +352,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -377,22 +455,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -426,7 +492,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -466,7 +532,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -503,7 +569,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -540,7 +606,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -633,7 +699,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -661,7 +727,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -689,7 +755,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -719,67 +785,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -788,68 +794,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -858,7 +857,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -873,71 +872,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -970,109 +962,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -1080,10 +1065,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -1107,6 +1094,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -1114,20 +1107,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -1148,28 +1132,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1197,7 +1174,7 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_TAB ; 23 TAB ENDP pop namespace -#line 118 "subrec.bas" +#line 118 "zx48k/subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1508,7 +1485,7 @@ __PRINT_STR: jp __PRINT_STR_LOOP ENDP pop namespace -#line 119 "subrec.bas" +#line 119 "zx48k/subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" @@ -1529,7 +1506,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 @@ -1709,7 +1686,7 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" -#line 120 "subrec.bas" +#line 120 "zx48k/subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" @@ -1807,7 +1784,7 @@ __PRINTU_LOOP: ENDP pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" -#line 121 "subrec.bas" +#line 121 "zx48k/subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sub32.asm" ; SUB32 ; Perform TOP of the stack - DEHL @@ -1834,5 +1811,5 @@ __SUB32: exx ret pop namespace -#line 122 "subrec.bas" +#line 122 "zx48k/subrec.bas" END diff --git a/tests/functional/zx48k/tap_00.tap b/tests/functional/zx48k/tap_00.tap index 462c0974b..17b014772 100644 Binary files a/tests/functional/zx48k/tap_00.tap and b/tests/functional/zx48k/tap_00.tap differ diff --git a/tests/functional/zx48k/tzx_00.tzx b/tests/functional/zx48k/tzx_00.tzx index f87577e9d..d18a89e29 100644 Binary files a/tests/functional/zx48k/tzx_00.tzx and b/tests/functional/zx48k/tzx_00.tzx differ diff --git a/tests/functional/zx48k/usr0.asm b/tests/functional/zx48k/usr0.asm index 2d230065b..3de2edd3a 100644 --- a/tests/functional/zx48k/usr0.asm +++ b/tests/functional/zx48k/usr0.asm @@ -50,77 +50,40 @@ DEFB 41h ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -; vim:ts=4:sw=4:et: ; 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/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation - push namespace core -CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl - ld hl, 1821h - ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP - pop namespace -#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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/arch/zx48k/library-asm/sposn.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + ; Attribute routines +; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: @@ -155,22 +118,20 @@ __STOP: ld (ERR_NR), a ret pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" +#line 6 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" +#line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" push namespace core __IN_SCREEN: ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) + ; are OUT of the screen limits PROC LOCAL __IN_SCREEN_ERR - ld hl, MAXX + ld hl, SCR_SIZE ld a, e - cp (hl) + cp l jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + cp h ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: @@ -179,7 +140,93 @@ __OUT_OF_SCREEN_ERR: jp __STOP ; Saves error code and exits ENDP pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 7 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core +__ATTR_ADDR: + ; calc start address in DE (as (32 * d) + e) + ; Contributed by Santiago Romero at http://www.speccy.org + 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/arch/zx48k/library-asm/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/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A @@ -196,22 +243,10 @@ JUMP_HL_PLUS_DE: ; Does JP (HL + DE) CALL_HL: jp (hl) pop namespace -#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register -#line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" - ; Global constants - push namespace core - P_FLAG EQU 23697 - FLAGS2 EQU 23681 - ATTR_P EQU 23693 ; permanet ATTRIBUTES - ATTR_T EQU 23695 ; temporary ATTRIBUTES - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - UDG EQU 23675 ; Pointer to UDG Charset - MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars - pop namespace -#line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" push namespace core INK: PROC @@ -245,7 +280,7 @@ INK_TMP: jp __SET_INK ENDP pop namespace -#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register @@ -285,7 +320,7 @@ PAPER_TMP: jp __SET_PAPER ENDP pop namespace -#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -322,7 +357,7 @@ FLASH_TMP: jr __SET_FLASH ENDP pop namespace -#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register @@ -359,7 +394,7 @@ BRIGHT_TMP: jr __SET_BRIGHT ENDP pop namespace -#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register @@ -452,7 +487,7 @@ OVER_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register @@ -480,7 +515,7 @@ INVERSE_TMP: jp __SET_ATTR_MODE ENDP pop namespace -#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register @@ -508,7 +543,7 @@ BOLD_TMP: ret ENDP pop namespace -#line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register @@ -538,67 +573,7 @@ ITALIC_TMP: ret ENDP pop namespace -#line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: - push namespace core -__ATTR_ADDR: - ; calc start address in DE (as (32 * d) + e) - ; Contributed by Santiago Romero at http://www.speccy.org - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - 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 - ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) - add hl, de - ld de, (SCREEN_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; 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 -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - PROC - call __ATTR_ADDR -__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 - ; Sets the attribute at a given screen pixel address in hl - ; HL contains the address in RAM for a given pixel (not a coordinate) -SET_PIXEL_ADDR_ATTR: - ;; gets ATTR position with offset given in SCREEN_ADDR - ld a, h - rrca - rrca - rrca - and 3 - or 18h - ld h, a - ld de, (SCREEN_ADDR) - add hl, de ;; Final screen addr - jp __SET_ATTR2 - pop namespace -#line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. @@ -607,68 +582,61 @@ __PRINT_INIT: ; To be called before program starts (initializes library) PROC ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + 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_CONT - LOCAL __PRINT_CONT2 LOCAL __PRINT_JUMP LOCAL __SRCADDR LOCAL __PRINT_UDG LOCAL __PRGRAPH LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch - PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 + PRINT_JUMP_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 - LOCAL __SCROLL -__SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: +__PRINT_CHR: cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN - ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address + 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 88 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +2: + call SET_SCR_ADDR + jr 4f +1: + ld (S_POSN), hl +4: ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) + 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 @@ -677,7 +645,7 @@ __PRINT_START: __PRINT_UDG: sub 90h ; Sub ASC code ld bc, (UDG) - jp __PRGRAPH0 + jr __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: ld bc, (CHARS) @@ -692,71 +660,64 @@ __PRGRAPH: ex de, hl ; HL = Write Address, DE = CHARS address bit 2, (iy + $47) call nz, __BOLD +#line 135 "/zxbasic/src/arch/zx48k/library-asm/print.asm" bit 4, (iy + $47) call nz, __ITALIC +#line 140 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (DFCC) + push hl ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen ; Set it with: ; LD A, ; LD (PRINT_MODE), A ; - ; Available opertions: + ; Available operations: ; NORMAL : 0h --> NOP ; OVER 0 ; XOR : AEh --> XOR (HL) ; OVER 1 ; OR : B6h --> OR (HL) ; PUTSPRITE ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + nop ; Set to one of the values above INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 ld (hl), a inc de inc h ; Next line djnz __PRCHAR - call __LOAD_S_POSN - push de + pop hl + inc hl + ld (DFCC), hl + ld hl, (DFCCL) ; current ATTR Pos + push hl call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 -__PRINT_CONT: - call __SAVE_S_POSN -__PRINT_CONT2: + pop hl + inc hl + ld (DFCCL),hl exx ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx ld hl, __PRINT_TABLE jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN -__PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 -__PRINT_EOL2: - ld a, d - inc a -__PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (S_POSN) + dec l + jr nz, 1f + dec h + jr nz, 1f + inc h + push hl + call __SCROLL_SCR + pop hl +#line 206 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +1: + ld l, 1 __PRINT_EOL_END: - ld d, a -__PRINT_AT2_END: - call __SAVE_S_POSN + call SET_SCR_ADDR exx ret __PRINT_COM: @@ -789,109 +750,102 @@ __PRINT_TAB2: pop de pop hl ret +__PRINT_AT: + ld hl, __PRINT_AT1 + jr __PRINT_SET_STATE __PRINT_NOP: __PRINT_RESTART: ld hl, __PRINT_START - jr __PRINT_SET_STATE -__PRINT_AT: - ld hl, __PRINT_AT1 __PRINT_SET_STATE: ld (PRINT_JUMP_STATE), hl ; Saves next entry call exx ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx + ld hl, (S_POSN) + ld a, SCR_ROWS + sub h + ld (S_POSN + 1), a ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + jr __PRINT_SET_STATE __PRINT_AT2: - exx ld hl, __PRINT_START ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + ld hl, (S_POSN) + ld a, SCR_COLS + sub l + ld l, a + jr __PRINT_EOL_END __PRINT_DEL: call __LOAD_S_POSN ; Gets current screen position dec e ld a, -1 cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e + jr nz, 3f + ld e, SCR_COLS - 2 dec d cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + jr nz, 3f + ld d, SCR_ROWS - 1 +3: + call __SAVE_S_POSN + exx + ret __PRINT_INK: ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INK2: - exx call INK_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_PAP: ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_PAP2: - exx call PAPER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_FLA: ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_FLA2: - exx call FLASH_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BRI: ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_BRI2: - exx call BRIGHT_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_INV: ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_INV2: - exx call INVERSE_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_OVR: ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + jr __PRINT_SET_STATE __PRINT_OVR2: - exx call OVER_TMP - jp __PRINT_RESTART + jr __PRINT_RESTART __PRINT_BOLD: ld hl, __PRINT_BOLD2 jp __PRINT_SET_STATE __PRINT_BOLD2: - exx call BOLD_TMP jp __PRINT_RESTART +#line 352 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_ITA: ld hl, __PRINT_ITA2 jp __PRINT_SET_STATE __PRINT_ITA2: - exx call ITALIC_TMP jp __PRINT_RESTART +#line 362 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __BOLD __BOLD: push hl ld hl, MEM0 ld b, 8 -__BOLD_LOOP: +1: ld a, (de) ld c, a rlca @@ -899,10 +853,12 @@ __BOLD_LOOP: ld (hl), a inc hl inc de - djnz __BOLD_LOOP + djnz 1b pop hl ld de, MEM0 ret +#line 383 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __ITALIC __ITALIC: push hl ld hl, MEM0 @@ -926,6 +882,12 @@ __ITALIC: pop hl ld de, MEM0 ret +#line 411 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __SCROLL_SCR +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL +#line 487 "/zxbasic/src/arch/zx48k/library-asm/print.asm" +#line 488 "/zxbasic/src/arch/zx48k/library-asm/print.asm" PRINT_COMMA: call __LOAD_S_POSN ld a, e @@ -933,20 +895,11 @@ PRINT_COMMA: add a, 16 PRINT_TAB: PROC - LOCAL LOOP, CONTINUE - inc a + LOCAL LOOP call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 -CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E + sub e + and 31 + ret z ld b, a LOOP: ld a, ' ' @@ -967,28 +920,21 @@ PRINT_AT: ; Changes cursor to ROW, COL ex de, hl call __IN_SCREEN ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" jp __SAVE_S_POSN LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 LOCAL __PRINT_AT1 LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 LOCAL __PRINT_INK LOCAL __PRINT_PAP LOCAL __PRINT_SET_STATE LOCAL __PRINT_TABLE LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + LOCAL __PRINT_ITA2 +#line 546 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + LOCAL __PRINT_BOLD2 +#line 552 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_TABLE: ; Jump table for 0 .. 22 codes DW __PRINT_NOP ; 0 DW __PRINT_NOP ; 1 @@ -1037,7 +983,7 @@ __PRINTU_CONT: djnz __PRINTU_CONT ret ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers +__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 diff --git a/tests/functional/zx48k/warn_unreach0.asm b/tests/functional/zx48k/warn_unreach0.asm index da0d5fadc..62b21fff9 100644 --- a/tests/functional/zx48k/warn_unreach0.asm +++ b/tests/functional/zx48k/warn_unreach0.asm @@ -49,68 +49,60 @@ _mySub__leave: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" - ; JUMPS directly to spectrum CLS - ; This routine does not clear lower screen - ;CLS EQU 0DAFh - ; Our faster implementation -#line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" - ; Printing positioning library. - push namespace core - PROC - LOCAL ECHO_E -__LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret -__SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret - ECHO_E EQU 23682 - MAXX EQU ECHO_E ; Max X position + 1 - MAXY EQU MAXX + 1 ; Max Y position + 1 - S_POSN EQU 23688 - POSX EQU S_POSN ; Current POS X - POSY EQU S_POSN + 1 ; Current POS Y - ENDP - pop namespace -#line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + ;; Clears the user screen (24 rows) +#line 1 "/zxbasic/src/arch/zx48k/library-asm/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 + TVFLAGS EQU 23612 ; TV Flags + 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 4 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" push namespace core CLS: PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN ld hl, 0 ld (COORDS), hl - ld hl, 1821h + ld hl, SCR_SIZE ld (S_POSN), hl -__CLS_SCR: - ld hl, SCREEN + ld hl, (SCREEN_ADDR) + ld (DFCC), hl ld (hl), 0 ld d, h ld e, l inc de - ld bc, 6144 + ld bc, 6143 ldir ; Now clear attributes + ld hl, (SCREEN_ATTR_ADDR) + ld (DFCCL), hl + ld d, h + ld e, l + inc de ld a, (ATTR_P) ld (hl), a ld bc, 767 ldir ret - COORDS EQU 23677 - SCREEN EQU 16384 ; Default start of the screen (can be changed) - ATTR_P EQU 23693 - ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address - SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen ENDP pop namespace #line 28 "zx48k/warn_unreach0.bas"