diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml
index a31d101fb..0508172d9 100644
--- a/.github/workflows/python-app.yml
+++ b/.github/workflows/python-app.yml
@@ -8,8 +8,6 @@ on:
branches:
- main
pull_request:
- branches:
- - main
branches-ignore:
- docs
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_global.asm b/tests/functional/arch/zx48k/opt1_dim_arr_global.asm
index e378623c5..7f710b47e 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_global.asm
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_global.asm
@@ -10,7 +10,6 @@
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
@@ -41,14 +40,11 @@ _a.__DATA__:
.core.__MAIN_PROGRAM__:
ld hl, 3
ld (_i), hl
- call .core.COPY_ATTR
- ld hl, (_i)
push hl
ld hl, _a
call .core.__ARRAY
ld a, (hl)
- call .core.__PRINTU8
- call .core.PRINT_EOL
+ ld (0), a
ld hl, 0
ld b, h
ld c, l
@@ -80,7 +76,7 @@ _a.__DATA__:
; O = [a0 + b0 * (a1 + b1 * (a2 + ... bN-2(aN-1)))]
; What I will do here is to calculate the following sequence:
; ((aN-1 * bN-2) + aN-2) * bN-3 + ...
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/mul16.asm"
+#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul16.asm"
push namespace core
__MUL16: ; Mutiplies HL with the last value stored into de stack
; Works for both signed and unsigned
@@ -220,1041 +216,5 @@ __FNMUL2:
ret
ENDP
pop namespace
-#line 27 "arch/zx48k/opt1_dim_arr_global.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 28 "arch/zx48k/opt1_dim_arr_global.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 30 "arch/zx48k/opt1_dim_arr_global.bas"
+#line 24 "arch/zx48k/opt1_dim_arr_global.bas"
END
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_global.bas b/tests/functional/arch/zx48k/opt1_dim_arr_global.bas
index bd6a1ebc7..bd54454c1 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_global.bas
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_global.bas
@@ -3,4 +3,4 @@ DIM a(5) as UByte => {0, 1, 2, 3, 4, 5}
DIM i as UInteger
i = 3
-PRINT a(i)
+POKE 0, a(i)
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_global2.asm b/tests/functional/arch/zx48k/opt1_dim_arr_global2.asm
index 578d2bcfd..14d162d0f 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_global2.asm
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_global2.asm
@@ -10,7 +10,6 @@
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
@@ -37,10 +36,8 @@ _a.__DATA__:
DEFB 01h
.core.ZXBASIC_USER_DATA_END:
.core.__MAIN_PROGRAM__:
- call .core.COPY_ATTR
ld a, (_a.__DATA__ + 2)
- call .core.__PRINTU8
- call .core.PRINT_EOL
+ ld (0), a
ld hl, 0
ld b, h
ld c, l
@@ -56,1040 +53,4 @@ _a.__DATA__:
ei
ret
;; --- end of user code ---
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 21 "arch/zx48k/opt1_dim_arr_global2.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 23 "arch/zx48k/opt1_dim_arr_global2.bas"
END
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_global2.bas b/tests/functional/arch/zx48k/opt1_dim_arr_global2.bas
index 448d8be54..bdd21633e 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_global2.bas
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_global2.bas
@@ -1,4 +1,4 @@
DIM a(5) as UByte => {0, 1, 2, 3, 4, 5}
-PRINT a(2)
+POKE 0, a(2)
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_global3.asm b/tests/functional/arch/zx48k/opt1_dim_arr_global3.asm
index 89ee6179e..c4977abae 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_global3.asm
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_global3.asm
@@ -10,7 +10,6 @@
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
@@ -39,10 +38,7 @@ _a.__DATA__:
.core.__MAIN_PROGRAM__:
ld a, 7
ld (_a.__DATA__ + 2), a
- call .core.COPY_ATTR
- ld a, (_a.__DATA__ + 2)
- call .core.__PRINTU8
- call .core.PRINT_EOL
+ ld (0), a
ld hl, 0
ld b, h
ld c, l
@@ -58,1040 +54,4 @@ _a.__DATA__:
ei
ret
;; --- end of user code ---
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 23 "arch/zx48k/opt1_dim_arr_global3.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 25 "arch/zx48k/opt1_dim_arr_global3.bas"
END
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_global3.bas b/tests/functional/arch/zx48k/opt1_dim_arr_global3.bas
index b15f879e6..d3459167d 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_global3.bas
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_global3.bas
@@ -2,4 +2,4 @@
DIM a(5) as UByte => {0, 1, 2, 3, 4, 5}
LET a(2) = 7
-PRINT a(2)
+POKE 0, a(2)
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_global4.asm b/tests/functional/arch/zx48k/opt1_dim_arr_global4.asm
index b1dd06e69..4a8eef20f 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_global4.asm
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_global4.asm
@@ -10,7 +10,6 @@
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
@@ -45,14 +44,12 @@ _a.__DATA__:
ld hl, _a
call .core.__ARRAY
ld (hl), 7
- call .core.COPY_ATTR
ld hl, (_i)
push hl
ld hl, _a
call .core.__ARRAY
ld a, (hl)
- call .core.__PRINTU8
- call .core.PRINT_EOL
+ ld (0), a
ld hl, 0
ld b, h
ld c, l
@@ -84,7 +81,7 @@ _a.__DATA__:
; O = [a0 + b0 * (a1 + b1 * (a2 + ... bN-2(aN-1)))]
; What I will do here is to calculate the following sequence:
; ((aN-1 * bN-2) + aN-2) * bN-3 + ...
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/mul16.asm"
+#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul16.asm"
push namespace core
__MUL16: ; Mutiplies HL with the last value stored into de stack
; Works for both signed and unsigned
@@ -224,1041 +221,5 @@ __FNMUL2:
ret
ENDP
pop namespace
-#line 31 "arch/zx48k/opt1_dim_arr_global4.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 32 "arch/zx48k/opt1_dim_arr_global4.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 34 "arch/zx48k/opt1_dim_arr_global4.bas"
+#line 29 "arch/zx48k/opt1_dim_arr_global4.bas"
END
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_global4.bas b/tests/functional/arch/zx48k/opt1_dim_arr_global4.bas
index 8f73c19b6..ddc8025af 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_global4.bas
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_global4.bas
@@ -4,4 +4,4 @@ DIM i as UInteger
i = 3
LET a(i) = 7
-PRINT a(i)
+POKE 0, a(i)
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_local2.asm b/tests/functional/arch/zx48k/opt1_dim_arr_local2.asm
index 159ee2efb..7738c136c 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_local2.asm
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_local2.asm
@@ -11,7 +11,6 @@
ld (.core.__CALL_BACK__), hl
ei
call .core.__MEM_INIT
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
@@ -54,15 +53,13 @@ _test:
ld de, .LABEL.__LABEL0
ld bc, 6
call .core.__ALLOC_INITIALIZED_LOCAL_ARRAY
- call .core.COPY_ATTR
ld l, (ix-2)
ld h, (ix-1)
inc hl
inc hl
inc hl
ld a, (hl)
- call .core.__PRINTU8
- call .core.PRINT_EOL
+ ld (0), a
_test__leave:
ex af, af'
exx
@@ -487,886 +484,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY:
ret
#line 139 "/zxbasic/src/lib/arch/zx48k/runtime/arrayalloc.asm"
pop namespace
-#line 51 "arch/zx48k/opt1_dim_arr_local2.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 52 "arch/zx48k/opt1_dim_arr_local2.bas"
+#line 49 "arch/zx48k/opt1_dim_arr_local2.bas"
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
; vim: ts=4:et:sw=4:
; Copyleft (K) by Jose M. Rodriguez de la Rosa
@@ -1525,129 +643,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed
ret
ENDP
pop namespace
-#line 53 "arch/zx48k/opt1_dim_arr_local2.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 55 "arch/zx48k/opt1_dim_arr_local2.bas"
+#line 50 "arch/zx48k/opt1_dim_arr_local2.bas"
.LABEL.__LABEL0:
DEFB 00h
DEFB 00h
diff --git a/tests/functional/arch/zx48k/opt1_dim_arr_local2.bas b/tests/functional/arch/zx48k/opt1_dim_arr_local2.bas
index 24d38c88e..0b3602fc6 100644
--- a/tests/functional/arch/zx48k/opt1_dim_arr_local2.bas
+++ b/tests/functional/arch/zx48k/opt1_dim_arr_local2.bas
@@ -1,6 +1,6 @@
FUNCTION test as UByte
DIM a(5) as UByte => {0, 1, 2, 3, 4, 5}
- PRINT a(3)
+ POKE 0, a(3)
END FUNCTION
test
diff --git a/tests/functional/arch/zx48k/opt2_fastcall_func.asm b/tests/functional/arch/zx48k/opt2_fastcall_func.asm
index fc2887e30..50f23a634 100644
--- a/tests/functional/arch/zx48k/opt2_fastcall_func.asm
+++ b/tests/functional/arch/zx48k/opt2_fastcall_func.asm
@@ -10,7 +10,6 @@
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
@@ -43,10 +42,8 @@ _test:
push ix
ld ix, 0
add ix, sp
- call .core.COPY_ATTR
ld a, (ix+5)
- call .core.__PRINTU8
- call .core.PRINT_EOL
+ ld (0), a
ld a, (ix+5)
inc a
_test__leave:
@@ -84,1040 +81,4 @@ _c2:
_c2__leave:
ret
;; --- end of user code ---
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 65 "arch/zx48k/opt2_fastcall_func.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 67 "arch/zx48k/opt2_fastcall_func.bas"
END
diff --git a/tests/functional/arch/zx48k/opt2_fastcall_func.bas b/tests/functional/arch/zx48k/opt2_fastcall_func.bas
index 0c5a20e42..9f43401d3 100644
--- a/tests/functional/arch/zx48k/opt2_fastcall_func.bas
+++ b/tests/functional/arch/zx48k/opt2_fastcall_func.bas
@@ -1,7 +1,7 @@
function test(a as UByte) as Ubyte
DIM x as Uinteger = 1
- print(a)
+ POKE 0, a
return a + 1
end function
diff --git a/tests/functional/arch/zx48k/opt2_func_call.asm b/tests/functional/arch/zx48k/opt2_func_call.asm
index 6d359152c..e2e7be064 100644
--- a/tests/functional/arch/zx48k/opt2_func_call.asm
+++ b/tests/functional/arch/zx48k/opt2_func_call.asm
@@ -10,7 +10,6 @@
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
@@ -41,10 +40,8 @@ _test:
push ix
ld ix, 0
add ix, sp
- call .core.COPY_ATTR
ld a, (ix+5)
- call .core.__PRINTU8
- call .core.PRINT_EOL
+ ld (0), a
ld a, (ix+5)
inc a
_test__leave:
@@ -62,1040 +59,4 @@ _c1:
_c1__leave:
ret
;; --- end of user code ---
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 43 "arch/zx48k/opt2_func_call.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 45 "arch/zx48k/opt2_func_call.bas"
END
diff --git a/tests/functional/arch/zx48k/opt2_func_call.bas b/tests/functional/arch/zx48k/opt2_func_call.bas
index 134a75c8c..37da401f4 100644
--- a/tests/functional/arch/zx48k/opt2_func_call.bas
+++ b/tests/functional/arch/zx48k/opt2_func_call.bas
@@ -1,7 +1,7 @@
REM Should ignore c2 and c3, never used
function test(a as UByte) as Ubyte
DIM x as Uinteger = 1
- print(a)
+ poke 0, a
return a + 1
end function
diff --git a/tests/functional/arch/zx48k/opt3_data2.asm b/tests/functional/arch/zx48k/opt3_data2.asm
index 52f681f72..4cc2133e0 100644
--- a/tests/functional/arch/zx48k/opt3_data2.asm
+++ b/tests/functional/arch/zx48k/opt3_data2.asm
@@ -11,7 +11,6 @@
ld (.core.__CALL_BACK__), hl
ei
call .core.__MEM_INIT
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
@@ -63,7 +62,6 @@ _a.__DATA__:
call .core.__ARRAY
pop af
ld (hl), a
- call .core.COPY_ATTR
ld a, (_i)
ld l, a
ld h, 0
@@ -71,8 +69,7 @@ _a.__DATA__:
ld hl, _a
call .core.__ARRAY
ld a, (hl)
- call .core.__PRINTU8
- call .core.PRINT_EOL
+ ld (0), a
ld hl, _i
inc (hl)
.LABEL.__LABEL0:
@@ -189,7 +186,7 @@ __MUL8B:
ret ; result = HL
ENDP
pop namespace
-#line 97 "arch/zx48k/opt3_data2.bas"
+#line 95 "arch/zx48k/opt3_data2.bas"
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/array.asm"
; vim: ts=4:et:sw=4:
; Copyleft (K) by Jose M. Rodriguez de la Rosa
@@ -346,43 +343,25 @@ __FNMUL2:
ret
ENDP
pop namespace
-#line 98 "arch/zx48k/opt3_data2.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
+#line 96 "arch/zx48k/opt3_data2.bas"
+#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
+ ;; This implements READ & RESTORE functions
+ ;; Reads a new element from the DATA Address code
+ ;; Updates the DATA_ADDR read ptr for the next read
+ ;; Data codification is 1 byte for type followed by data bytes
+ ;; Byte type is encoded as follows
+;; 00: End of data
+;; 01: String
+;; 02: Byte
+;; 03: Ubyte
+;; 04: Integer
+;; 05: UInteger
+;; 06: Long
+;; 07: ULong
+;; 08: Fixed
+;; 09: Float
+ ;; bit7 is set for a parameter-less function
+ ;; In that case, the next two bytes are the ptr of the function to jump
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
; Simple error control routines
; vim:ts=4:et:
@@ -417,990 +396,7 @@ __STOP:
ld (ERR_NR), a
ret
pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 99 "arch/zx48k/opt3_data2.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 101 "arch/zx48k/opt3_data2.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
- ;; This implements READ & RESTORE functions
- ;; Reads a new element from the DATA Address code
- ;; Updates the DATA_ADDR read ptr for the next read
- ;; Data codification is 1 byte for type followed by data bytes
- ;; Byte type is encoded as follows
-;; 00: End of data
-;; 01: String
-;; 02: Byte
-;; 03: Ubyte
-;; 04: Integer
-;; 05: UInteger
-;; 06: Long
-;; 07: ULong
-;; 08: Fixed
-;; 09: Float
- ;; bit7 is set for a parameter-less function
- ;; In that case, the next two bytes are the ptr of the function to jump
+#line 23 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm"
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm"
; vim: ts=4:et:sw=4:
@@ -2437,5 +1433,5 @@ __DATA_ADDR: ;; Stores current DATA ptr
dw .DATA.__DATA__0
ENDP
pop namespace
-#line 102 "arch/zx48k/opt3_data2.bas"
+#line 97 "arch/zx48k/opt3_data2.bas"
END
diff --git a/tests/functional/arch/zx48k/opt3_data2.bas b/tests/functional/arch/zx48k/opt3_data2.bas
index 0a2a90670..88d5d1697 100644
--- a/tests/functional/arch/zx48k/opt3_data2.bas
+++ b/tests/functional/arch/zx48k/opt3_data2.bas
@@ -2,7 +2,7 @@ DIM a(9) AS UBYTE
FOR i = 0 TO 9: REM 0 TO 9 => 10 elements
READ a(i)
- PRINT a(i)
+ POKE 0, a(i)
NEXT i
REM notice the a * a expression
diff --git a/tests/functional/arch/zx48k/opt3_einar.asm b/tests/functional/arch/zx48k/opt3_einar.asm
index 2d04a02cf..59d7da62e 100644
--- a/tests/functional/arch/zx48k/opt3_einar.asm
+++ b/tests/functional/arch/zx48k/opt3_einar.asm
@@ -10,16 +10,10 @@
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
- call .core.__MEM_INIT
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
.core.ZXBASIC_USER_DATA:
- ; Defines HEAP SIZE
-.core.ZXBASIC_HEAP_SIZE EQU 4768
-.core.ZXBASIC_MEM_HEAP:
- DEFS 4768
; Defines USER DATA Length in bytes
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
@@ -51,1255 +45,15 @@ _x2:
sub (ix-1)
ccf
jp nc, .LABEL.__LABEL0
- call .core.COPY_ATTR
- ld hl, .LABEL.__LABEL2
- xor a
- call .core.__PRINTSTR
- call .core.PRINT_EOL
+ ld a, (ix-1)
+ ld (0), a
jp _x2__leave
.LABEL.__LABEL0:
- call .core.COPY_ATTR
- ld hl, .LABEL.__LABEL3
- xor a
- call .core.__PRINTSTR
- call .core.PRINT_EOL
+ ld a, (ix-1)
+ ld (1), a
_x2__leave:
ld sp, ix
pop ix
ret
-.LABEL.__LABEL2:
- DEFW 0003h
- DEFB 4Fh
- DEFB 70h
- DEFB 73h
-.LABEL.__LABEL3:
- DEFW 0002h
- DEFB 4Fh
- DEFB 4Bh
;; --- end of user code ---
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 53 "arch/zx48k/opt3_einar.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
- ; ---------------------------------------------------------------------
- ; __MEM_INIT must be called to initalize this library with the
- ; standard parameters
- ; ---------------------------------------------------------------------
- push namespace core
-__MEM_INIT: ; Initializes the library using (RAMTOP) as start, and
- ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start
- ld de, ZXBASIC_HEAP_SIZE ; Change this with your size
- ; ---------------------------------------------------------------------
- ; __MEM_INIT2 initalizes this library
-; Parameters:
-; HL : Memory address of 1st byte of the memory heap
-; DE : Length in bytes of the Memory Heap
- ; ---------------------------------------------------------------------
-__MEM_INIT2:
- ; HL as TOP
- PROC
- dec de
- dec de
- dec de
- dec de ; DE = length - 4; HL = start
- ; This is done, because we require 4 bytes for the empty dummy-header block
- xor a
- ld (hl), a
- inc hl
- ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4
- inc hl
- ld b, h
- ld c, l
- inc bc
- inc bc ; BC = starts of next block
- ld (hl), c
- inc hl
- ld (hl), b
- inc hl ; Pointer to next block
- ld (hl), e
- inc hl
- ld (hl), d
- inc hl ; Block size (should be length - 4 at start); This block contains all the available memory
- ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block)
- inc hl
- ld (hl), a
- ld a, 201
- ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again
- ret
- ENDP
- pop namespace
-#line 69 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
- ; ---------------------------------------------------------------------
- ; MEM_FREE
- ; Frees a block of memory
- ;
-; Parameters:
- ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing
- ; is done
- ; ---------------------------------------------------------------------
- push namespace core
-MEM_FREE:
-__MEM_FREE: ; Frees the block pointed by HL
- ; HL DE BC & AF modified
- PROC
- LOCAL __MEM_LOOP2
- LOCAL __MEM_LINK_PREV
- LOCAL __MEM_JOIN_TEST
- LOCAL __MEM_BLOCK_JOIN
- ld a, h
- or l
- ret z ; Return if NULL pointer
- dec hl
- dec hl
- ld b, h
- ld c, l ; BC = Block pointer
- ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start
-__MEM_LOOP2:
- inc hl
- inc hl ; Next block ptr
- ld e, (hl)
- inc hl
- ld d, (hl) ; Block next ptr
- ex de, hl ; DE = &(block->next); HL = block->next
- ld a, h ; HL == NULL?
- or l
- jp z, __MEM_LINK_PREV; if so, link with previous
- or a ; Clear carry flag
- sbc hl, bc ; Carry if BC > HL => This block if before
- add hl, bc ; Restores HL, preserving Carry flag
- jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block
- ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next
-__MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL
- ex de, hl
- push hl
- dec hl
- ld (hl), c
- inc hl
- ld (hl), b ; (DE) <- BC
- ld h, b ; HL <- BC (Free block ptr)
- ld l, c
- inc hl ; Skip block length (2 bytes)
- inc hl
- ld (hl), e ; Block->next = DE
- inc hl
- ld (hl), d
- ; --- LINKED ; HL = &(BC->next) + 2
- call __MEM_JOIN_TEST
- pop hl
-__MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them
- ; hl = Ptr to current block + 2
- ld d, (hl)
- dec hl
- ld e, (hl)
- dec hl
- ld b, (hl) ; Loads block length into BC
- dec hl
- ld c, (hl) ;
- push hl ; Saves it for later
- add hl, bc ; Adds its length. If HL == DE now, it must be joined
- or a
- sbc hl, de ; If Z, then HL == DE => We must join
- pop hl
- ret nz
-__MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC
- push hl ; Saves it for later
- ex de, hl
- ld e, (hl) ; DE -> block->next->length
- inc hl
- ld d, (hl)
- inc hl
- ex de, hl ; DE = &(block->next)
- add hl, bc ; HL = Total Length
- ld b, h
- ld c, l ; BC = Total Length
- ex de, hl
- ld e, (hl)
- inc hl
- ld d, (hl) ; DE = block->next
- pop hl ; Recovers Pointer to block
- ld (hl), c
- inc hl
- ld (hl), b ; Length Saved
- inc hl
- ld (hl), e
- inc hl
- ld (hl), d ; Next saved
- ret
- ENDP
- pop namespace
-#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm"
- ; PRINT command routine
- ; Prints string pointed by HL
- push namespace core
-PRINT_STR:
-__PRINTSTR: ; __FASTCALL__ Entry to print_string
- PROC
- LOCAL __PRINT_STR_LOOP
- LOCAL __PRINT_STR_END
- ld d, a ; Saves A reg (Flag) for later
- ld a, h
- or l
- ret z ; Return if the pointer is NULL
- push hl
- ld c, (hl)
- inc hl
- ld b, (hl)
- inc hl ; BC = LEN(a$); HL = &a$
-__PRINT_STR_LOOP:
- ld a, b
- or c
- jr z, __PRINT_STR_END ; END if BC (counter = 0)
- ld a, (hl)
- call __PRINTCHAR
- inc hl
- dec bc
- jp __PRINT_STR_LOOP
-__PRINT_STR_END:
- pop hl
- ld a, d ; Recovers A flag
- or a ; If not 0 this is a temporary string. Free it
- ret z
- jp __MEM_FREE ; Frees str from heap and return from there
-__PRINT_STR:
- ; Fastcall Entry
- ; It ONLY prints strings
- ; HL = String start
- ; BC = String length (Number of chars)
- push hl ; Push str address for later
- ld d, a ; Saves a FLAG
- jp __PRINT_STR_LOOP
- ENDP
- pop namespace
-#line 55 "arch/zx48k/opt3_einar.bas"
END
diff --git a/tests/functional/arch/zx48k/opt3_einar.bas b/tests/functional/arch/zx48k/opt3_einar.bas
index 270b4886b..3ba9879fa 100644
--- a/tests/functional/arch/zx48k/opt3_einar.bas
+++ b/tests/functional/arch/zx48k/opt3_einar.bas
@@ -3,9 +3,9 @@ sub x2()
LET a = 129
IF (a <= 32) THEN
- PRINT "Ops"
+ POKE 0, a
ELSE
- PRINT "OK"
+ POKE 1, a
END IF
end sub
diff --git a/tests/functional/arch/zx48k/read10.asm b/tests/functional/arch/zx48k/read10.asm
deleted file mode 100644
index 90c28a250..000000000
--- a/tests/functional/arch/zx48k/read10.asm
+++ /dev/null
@@ -1,2357 +0,0 @@
- org 32768
-.core.__START_PROGRAM:
- di
- push ix
- push iy
- exx
- push hl
- exx
- ld hl, 0
- add hl, sp
- ld (.core.__CALL_BACK__), hl
- ei
- call .core.__MEM_INIT
- call .core.__PRINT_INIT
- jp .core.__MAIN_PROGRAM__
-.core.__CALL_BACK__:
- DEFW 0
-.core.ZXBASIC_USER_DATA:
- ; Defines HEAP SIZE
-.core.ZXBASIC_HEAP_SIZE EQU 4768
-.core.ZXBASIC_MEM_HEAP:
- DEFS 4768
- ; Defines USER DATA Length in bytes
-.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
- .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
- .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
-_v:
- DEFB 81h
- DEFB 40h
- DEFB 00h
- DEFB 00h
- DEFB 00h
-.core.ZXBASIC_USER_DATA_END:
-.core.__MAIN_PROGRAM__:
- ld hl, .DATA.__DATA__0
- call .core.__RESTORE
- call _p
- ld hl, 0
- ld b, h
- ld c, l
-.core.__END_PROGRAM:
- di
- ld hl, (.core.__CALL_BACK__)
- ld sp, hl
- exx
- pop hl
- exx
- pop iy
- pop ix
- ei
- ret
-_p:
- push ix
- ld ix, 0
- add ix, sp
- ld hl, 0
- push hl
- push hl
- push hl
- ld (ix-1), 0
- jp .LABEL.__LABEL0
-.LABEL.__LABEL3:
- ld a, 9
- call .core.__READ
- ld hl, -6
- call .core.__PSTOREF
- call .core.COPY_ATTR
- push ix
- pop hl
- ld de, -6
- add hl, de
- call .core.__PLOADF
- call .core.__PRINTF
- call .core.PRINT_EOL
-.LABEL.__LABEL4:
- inc (ix-1)
-.LABEL.__LABEL0:
- ld a, (ix-1)
- push af
- ld a, 3
- pop hl
- cp h
- jp nc, .LABEL.__LABEL3
-.LABEL.__LABEL2:
-_p__leave:
- ld sp, ix
- pop ix
- ret
-___DATA__FUNCPTR__0:
- ld a, (_v)
- ld de, (_v + 1)
- ld bc, (_v + 3)
- ld hl, 00000h
- push hl
- ld hl, 00048h
- push hl
- ld h, 085h
- push hl
- call .core.__MULF
-___DATA__FUNCPTR__0__leave:
- ret
-___DATA__FUNCPTR__1:
- ld a, (_v)
- ld de, (_v + 1)
- ld bc, (_v + 3)
- call .core.SIN
- push bc
- push de
- push af
- ld a, (_v)
- ld de, (_v + 1)
- ld bc, (_v + 3)
- call .core.TAN
- push bc
- push de
- push af
- ld a, 082h
- ld de, 00000h
- ld bc, 00000h
- call .core.__POW
- call .core.__MULF
-___DATA__FUNCPTR__1__leave:
- ret
-___DATA__FUNCPTR__2:
- ld a, (_v)
- ld de, (_v + 1)
- ld bc, (_v + 3)
- ld hl, 0A2DAh
- push hl
- ld hl, 00F49h
- push hl
- ld h, 082h
- push hl
- call .core.__MULF
-___DATA__FUNCPTR__2__leave:
- ret
-.DATA.__DATA__0:
- DEFB 3
- DEFB 10
- DEFB 89h
- DEFW ___DATA__FUNCPTR__0
- DEFB 89h
- DEFW ___DATA__FUNCPTR__1
- DEFB 89h
- DEFW ___DATA__FUNCPTR__2
-__DATA__END:
- DEFB 00h
- ;; --- end of user code ---
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/stackf.asm"
- ; -------------------------------------------------------------
- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC
- ; -------------------------------------------------------------
- push namespace core
- __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB)
- __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB)
-__FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4)
- ; Second argument to push into the stack calculator is popped out of the stack
- ; Since the caller routine also receives the parameters into the top of the stack
- ; four bytes must be removed from SP before pop them out
- call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK
- exx
- pop hl ; Caller-Caller return addr
- exx
- pop hl ; Caller return addr
- pop af
- pop de
- pop bc
- push hl ; Caller return addr
- exx
- push hl ; Caller-Caller return addr
- exx
- jp __FPSTACK_PUSH
-__FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK
- ; This format is specified in the ZX 48K Manual
- ; You can push a 16 bit signed integer as
- ; 0 SS LL HH 0, being SS the sign and LL HH the low
- ; and High byte respectively
- ld a, h
- rla ; sign to Carry
- sbc a, a ; 0 if positive, FF if negative
- ld e, a
- ld d, l
- ld c, h
- xor a
- ld b, a
- jp __FPSTACK_PUSH
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf.asm"
- ; -------------------------------------------------------------
- ; Floating point library using the FP ROM Calculator (ZX 48K)
- ; All of them uses A EDCB registers as 1st paramter.
- ; For binary operators, the 2n operator must be pushed into the
- ; stack, in the order A DE BC.
- ;
- ; Uses CALLEE convention
- ; -------------------------------------------------------------
- push namespace core
-__MULF: ; Multiplication
- call __FPSTACK_PUSH2
- ; ------------- ROM MUL
- rst 28h
- defb 04h ;
- defb 38h; ; END CALC
- jp __FPSTACK_POP
- pop namespace
-#line 116 "arch/zx48k/read10.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 117 "arch/zx48k/read10.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm"
- ; -------------------------------------------------------------
- ; Floating point library using the FP ROM Calculator (ZX 48K)
- ; All of them uses A EDCB registers as 1st paramter.
- ; For binary operators, the 2n operator must be pushed into the
- ; stack, in the order A DE BC.
- ;
- ; Uses CALLEE convention
- ;
-; Operands comes swapped:
- ; 1 st parameter is the BASE (A ED CB)
- ; 2 nd parameter (Top of the stack) is Exponent
- ; -------------------------------------------------------------
- push namespace core
-__POW: ; Exponentiation
- PROC
- call __FPSTACK_PUSH2
- ; ------------- ROM POW
- rst 28h
- defb 01h ; Exchange => 1, Base
- defb 06h ; POW
- defb 38h; ; END CALC
- jp __FPSTACK_POP
- ENDP
- pop namespace
-#line 118 "arch/zx48k/read10.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm"
- push namespace core
-SIN: ; Computes SIN using ROM FP-CALC
- call __FPSTACK_PUSH
- rst 28h ; ROM CALC
- defb 1Fh
- defb 38h ; END CALC
- jp __FPSTACK_POP
- pop namespace
-#line 119 "arch/zx48k/read10.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm"
- push namespace core
-TAN: ; Computes TAN using ROM FP-CALC
- call __FPSTACK_PUSH
- rst 28h ; ROM CALC
- defb 21h ; TAN
- defb 38h ; END CALC
- jp __FPSTACK_POP
- pop namespace
-#line 120 "arch/zx48k/read10.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ploadf.asm"
- ; Parameter / Local var load
- ; A => Offset
- ; IX = Stack Frame
-; RESULT: HL => IX + DE
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iloadf.asm"
- ; __FASTCALL__ routine which
- ; loads a 40 bits floating point into A ED CB
- ; stored at position pointed by POINTER HL
- ;A DE, BC <-- ((HL))
- push namespace core
-__ILOADF:
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a
- ; __FASTCALL__ routine which
- ; loads a 40 bits floating point into A ED CB
- ; stored at position pointed by POINTER HL
- ;A DE, BC <-- (HL)
-__LOADF: ; Loads a 40 bits FP number from address pointed by HL
- ld a, (hl)
- inc hl
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld c, (hl)
- inc hl
- ld b, (hl)
- ret
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/ploadf.asm"
- push namespace core
-__PLOADF:
- push ix
- pop hl
- add hl, de
- jp __LOADF
- pop namespace
-#line 121 "arch/zx48k/read10.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printf.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
- ; ---------------------------------------------------------------------
- ; __MEM_INIT must be called to initalize this library with the
- ; standard parameters
- ; ---------------------------------------------------------------------
- push namespace core
-__MEM_INIT: ; Initializes the library using (RAMTOP) as start, and
- ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start
- ld de, ZXBASIC_HEAP_SIZE ; Change this with your size
- ; ---------------------------------------------------------------------
- ; __MEM_INIT2 initalizes this library
-; Parameters:
-; HL : Memory address of 1st byte of the memory heap
-; DE : Length in bytes of the Memory Heap
- ; ---------------------------------------------------------------------
-__MEM_INIT2:
- ; HL as TOP
- PROC
- dec de
- dec de
- dec de
- dec de ; DE = length - 4; HL = start
- ; This is done, because we require 4 bytes for the empty dummy-header block
- xor a
- ld (hl), a
- inc hl
- ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4
- inc hl
- ld b, h
- ld c, l
- inc bc
- inc bc ; BC = starts of next block
- ld (hl), c
- inc hl
- ld (hl), b
- inc hl ; Pointer to next block
- ld (hl), e
- inc hl
- ld (hl), d
- inc hl ; Block size (should be length - 4 at start); This block contains all the available memory
- ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block)
- inc hl
- ld (hl), a
- ld a, 201
- ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again
- ret
- ENDP
- pop namespace
-#line 69 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
- ; ---------------------------------------------------------------------
- ; MEM_FREE
- ; Frees a block of memory
- ;
-; Parameters:
- ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing
- ; is done
- ; ---------------------------------------------------------------------
- push namespace core
-MEM_FREE:
-__MEM_FREE: ; Frees the block pointed by HL
- ; HL DE BC & AF modified
- PROC
- LOCAL __MEM_LOOP2
- LOCAL __MEM_LINK_PREV
- LOCAL __MEM_JOIN_TEST
- LOCAL __MEM_BLOCK_JOIN
- ld a, h
- or l
- ret z ; Return if NULL pointer
- dec hl
- dec hl
- ld b, h
- ld c, l ; BC = Block pointer
- ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start
-__MEM_LOOP2:
- inc hl
- inc hl ; Next block ptr
- ld e, (hl)
- inc hl
- ld d, (hl) ; Block next ptr
- ex de, hl ; DE = &(block->next); HL = block->next
- ld a, h ; HL == NULL?
- or l
- jp z, __MEM_LINK_PREV; if so, link with previous
- or a ; Clear carry flag
- sbc hl, bc ; Carry if BC > HL => This block if before
- add hl, bc ; Restores HL, preserving Carry flag
- jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block
- ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next
-__MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL
- ex de, hl
- push hl
- dec hl
- ld (hl), c
- inc hl
- ld (hl), b ; (DE) <- BC
- ld h, b ; HL <- BC (Free block ptr)
- ld l, c
- inc hl ; Skip block length (2 bytes)
- inc hl
- ld (hl), e ; Block->next = DE
- inc hl
- ld (hl), d
- ; --- LINKED ; HL = &(BC->next) + 2
- call __MEM_JOIN_TEST
- pop hl
-__MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them
- ; hl = Ptr to current block + 2
- ld d, (hl)
- dec hl
- ld e, (hl)
- dec hl
- ld b, (hl) ; Loads block length into BC
- dec hl
- ld c, (hl) ;
- push hl ; Saves it for later
- add hl, bc ; Adds its length. If HL == DE now, it must be joined
- or a
- sbc hl, de ; If Z, then HL == DE => We must join
- pop hl
- ret nz
-__MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC
- push hl ; Saves it for later
- ex de, hl
- ld e, (hl) ; DE -> block->next->length
- inc hl
- ld d, (hl)
- inc hl
- ex de, hl ; DE = &(block->next)
- add hl, bc ; HL = Total Length
- ld b, h
- ld c, l ; BC = Total Length
- ex de, hl
- ld e, (hl)
- inc hl
- ld d, (hl) ; DE = block->next
- pop hl ; Recovers Pointer to block
- ld (hl), c
- inc hl
- ld (hl), b ; Length Saved
- inc hl
- ld (hl), e
- inc hl
- ld (hl), d ; Next saved
- ret
- ENDP
- pop namespace
-#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm"
- ; PRINT command routine
- ; Prints string pointed by HL
- push namespace core
-PRINT_STR:
-__PRINTSTR: ; __FASTCALL__ Entry to print_string
- PROC
- LOCAL __PRINT_STR_LOOP
- LOCAL __PRINT_STR_END
- ld d, a ; Saves A reg (Flag) for later
- ld a, h
- or l
- ret z ; Return if the pointer is NULL
- push hl
- ld c, (hl)
- inc hl
- ld b, (hl)
- inc hl ; BC = LEN(a$); HL = &a$
-__PRINT_STR_LOOP:
- ld a, b
- or c
- jr z, __PRINT_STR_END ; END if BC (counter = 0)
- ld a, (hl)
- call __PRINTCHAR
- inc hl
- dec bc
- jp __PRINT_STR_LOOP
-__PRINT_STR_END:
- pop hl
- ld a, d ; Recovers A flag
- or a ; If not 0 this is a temporary string. Free it
- ret z
- jp __MEM_FREE ; Frees str from heap and return from there
-__PRINT_STR:
- ; Fastcall Entry
- ; It ONLY prints strings
- ; HL = String start
- ; BC = String length (Number of chars)
- push hl ; Push str address for later
- ld d, a ; Saves a FLAG
- jp __PRINT_STR_LOOP
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printf.asm"
- push namespace core
-__PRINTF: ; Prints a Fixed point Number stored in C ED LH
- PROC
- LOCAL RECLAIM2
- LOCAL STK_END
- STK_END EQU 5C65h
- ld hl, (ATTR_T)
- push hl ; Saves ATTR_T since BUG ROM changes it
- ld hl, (STK_END)
- push hl ; Stores STK_END
- call __FPSTACK_PUSH ; Push number into stack
- rst 28h ; # Rom Calculator
- defb 2Eh ; # STR$(x)
- defb 38h ; # END CALC
- call __FPSTACK_POP ; Recovers string parameters to A ED CB
- pop hl
- ld (STK_END), hl ; Balance STK_END to avoid STR$ bug
- pop hl
- ld (ATTR_T), hl ; Restores ATTR_T
- ex de, hl ; String position now in HL
- push bc
- xor a ; Avoid the str to be FREED from heap
- call __PRINT_STR
- pop bc
- inc bc
- jp RECLAIM2 ; Frees TMP Memory
- RECLAIM2 EQU 19E8h
- ENDP
- pop namespace
-#line 123 "arch/zx48k/read10.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pstoref.asm"
- ; Stores FP number in A ED CB at location HL+IX
- ; HL = Offset
- ; IX = Stack Frame
- ; A ED CB = FP Number
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/storef.asm"
- push namespace core
-__PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL)
- push de
- ex de, hl ; DE <- HL
- push ix
- pop hl ; HL <- IX
- add hl, de ; HL <- IX + HL
- pop de
-__ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register
- ex af, af'
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a ; HL = (HL)
- ex af, af'
-__STOREF: ; Stores the given FP number in A EDCB at address HL
- ld (hl), a
- inc hl
- ld (hl), e
- inc hl
- ld (hl), d
- inc hl
- ld (hl), c
- inc hl
- ld (hl), b
- ret
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/pstoref.asm"
- ; Stored a float number in A ED CB into the address pointed by IX + HL
- push namespace core
-__PSTOREF:
- push de
- ex de, hl ; DE <- HL
- push ix
- pop hl ; HL <- IX
- add hl, de ; HL <- IX + DE
- pop de
- jp __STOREF
- pop namespace
-#line 124 "arch/zx48k/read10.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
- ;; This implements READ & RESTORE functions
- ;; Reads a new element from the DATA Address code
- ;; Updates the DATA_ADDR read ptr for the next read
- ;; Data codification is 1 byte for type followed by data bytes
- ;; Byte type is encoded as follows
-;; 00: End of data
-;; 01: String
-;; 02: Byte
-;; 03: Ubyte
-;; 04: Integer
-;; 05: UInteger
-;; 06: Long
-;; 07: ULong
-;; 08: Fixed
-;; 09: Float
- ;; bit7 is set for a parameter-less function
- ;; In that case, the next two bytes are the ptr of the function to jump
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the MIT license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the MIT license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be freed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
- ; ---------------------------------------------------------------------
- ; MEM_ALLOC
- ; Allocates a block of memory in the heap.
- ;
- ; Parameters
- ; BC = Length of requested memory block
- ;
-; Returns:
- ; HL = Pointer to the allocated block in memory. Returns 0 (NULL)
- ; if the block could not be allocated (out of memory)
- ; ---------------------------------------------------------------------
- push namespace core
-MEM_ALLOC:
-__MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC)
- PROC
- LOCAL __MEM_LOOP
- LOCAL __MEM_DONE
- LOCAL __MEM_SUBTRACT
- LOCAL __MEM_START
- LOCAL TEMP, TEMP0
- TEMP EQU TEMP0 + 1
- ld hl, 0
- ld (TEMP), hl
-__MEM_START:
- ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start
- inc bc
- inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer
-__MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE
- ld a, h ; HL = NULL (No memory available?)
- or l
-#line 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm"
- ret z ; NULL
-#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm"
- ; HL = Pointer to Free block
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl ; DE = Block Length
- push hl ; HL = *pointer to -> next block
- ex de, hl
- or a ; CF = 0
- sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length)
- jp nc, __MEM_DONE
- pop hl
- ld (TEMP), hl
- ex de, hl
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
- jp __MEM_LOOP
-__MEM_DONE: ; A free block has been found.
- ; Check if at least 4 bytes remains free (HL >= 4)
- push hl
- exx ; exx to preserve bc
- pop hl
- ld bc, 4
- or a
- sbc hl, bc
- exx
- jp nc, __MEM_SUBTRACT
- ; At this point...
- ; less than 4 bytes remains free. So we return this block entirely
- ; We must link the previous block with the next to this one
- ; (DE) => Pointer to next block
- ; (TEMP) => &(previous->next)
- pop hl ; Discard current block pointer
- push de
- ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a ; HL = (HL)
- ex de, hl ; HL = Previous block pointer; DE = Next block pointer
-TEMP0:
- ld hl, 0 ; Pre-previous block pointer
- ld (hl), e
- inc hl
- ld (hl), d ; LINKED
- pop hl ; Returning block.
- ret
-__MEM_SUBTRACT:
- ; At this point we have to store HL value (Length - BC) into (DE - 2)
- ex de, hl
- dec hl
- ld (hl), d
- dec hl
- ld (hl), e ; Store new block length
- add hl, de ; New length + DE => free-block start
- pop de ; Remove previous HL off the stack
- ld (hl), c ; Store length on its 1st word
- inc hl
- ld (hl), b
- inc hl ; Return hl
- ret
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm"
- ; Loads a string (ptr) from HL
- ; and duplicates it on dynamic memory again
- ; Finally, it returns result pointer in HL
- push namespace core
-__ILOADSTR: ; This is the indirect pointer entry HL = (HL)
- ld a, h
- or l
- ret z
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a
-__LOADSTR: ; __FASTCALL__ entry
- ld a, h
- or l
- ret z ; Return if NULL
- ld c, (hl)
- inc hl
- ld b, (hl)
- dec hl ; BC = LEN(a$)
- inc bc
- inc bc ; BC = LEN(a$) + 2 (two bytes for length)
- push hl
- push bc
- call __MEM_ALLOC
- pop bc ; Recover length
- pop de ; Recover origin
- ld a, h
- or l
- ret z ; Return if NULL (No memory)
- ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE
- push de ; Saves destiny start
- ldir ; Copies string (length number included)
- pop hl ; Recovers destiny in hl as result
- ret
- pop namespace
-#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iload32.asm"
- ; __FASTCALL__ routine which
- ; loads a 32 bits integer into DE,HL
- ; stored at position pointed by POINTER HL
- ; DE,HL <-- (HL)
- push namespace core
-__ILOAD32:
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a
- ex de, hl
- ret
- pop namespace
-#line 25 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm"
- push namespace core
-__ABS32:
- bit 7, d
- ret z
-__NEG32: ; Negates DEHL (Two's complement)
- ld a, l
- cpl
- ld l, a
- ld a, h
- cpl
- ld h, a
- ld a, e
- cpl
- ld e, a
- ld a, d
- cpl
- ld d, a
- inc l
- ret nz
- inc h
- ret nz
- inc de
- ret
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm"
- push namespace core
-__FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed)
- ; Input FP number in A EDCB (A exponent, EDCB mantissa)
- ; Output: DEHL 32 bit number (signed)
- PROC
- LOCAL __IS_FLOAT
- LOCAL __NEGATE
- or a
- jr nz, __IS_FLOAT
- ; Here if it is a ZX ROM Integer
- ld h, c
- ld l, d
- ld d, e
- ret
-__IS_FLOAT: ; Jumps here if it is a true floating point number
- ld h, e
- push hl ; Stores it for later (Contains Sign in H)
- push de
- push bc
- exx
- pop de ; Loads mantissa into C'B' E'D'
- pop bc ;
- set 7, c ; Highest mantissa bit is always 1
- exx
- ld hl, 0 ; DEHL = 0
- ld d, h
- ld e, l
- ;ld a, c ; Get exponent
- sub 128 ; Exponent -= 128
- jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128)
- jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0)
- ld b, a ; Loop counter = exponent - 128
-__FTOU32REG_LOOP:
- exx ; Shift C'B' E'D' << 1, output bit stays in Carry
- sla d
- rl e
- rl b
- rl c
- exx ; Shift DEHL << 1, inserting the carry on the right
- rl l
- rl h
- rl e
- rl d
- djnz __FTOU32REG_LOOP
-__FTOU32REG_END:
- pop af ; Take the sign bit
- or a ; Sets SGN bit to 1 if negative
- jp m, __NEGATE ; Negates DEHL
- ret
-__NEGATE:
- exx
- ld a, d
- or e
- or b
- or c
- exx
- jr z, __END
- inc l
- jr nz, __END
- inc h
- jr nz, __END
- inc de
- LOCAL __END
-__END:
- jp __NEG32
- ENDP
-__FTOU8: ; Converts float in C ED LH to Unsigned byte in A
- call __FTOU32REG
- ld a, l
- ret
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm"
- push namespace core
-__FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal
- ; Input FP number in A EDCB (A exponent, EDCB mantissa)
- ld l, a ; Saves exponent for later
- or d
- or e
- or b
- or c
- ld h, e
- ret z ; Return if ZERO
- push hl ; Stores it for later (Contains sign in H, exponent in L)
- push de
- push bc
- exx
- pop de ; Loads mantissa into C'B' E'D'
- pop bc ;
- set 7, c ; Highest mantissa bit is always 1
- exx
- ld hl, 0 ; DEHL = 0
- ld d, h
- ld e, l
- pop bc
- ld a, c ; Get exponent
- sub 112 ; Exponent -= 128 + 16
- push bc ; Saves sign in b again
- jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128)
- jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0)
- ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more)
- jp __FTOU32REG_LOOP ; proceed as an u32 integer
- pop namespace
-#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm"
- push namespace core
-__I8TOFREG:
- ld l, a
- rlca
- sbc a, a ; A = SGN(A)
- ld h, a
- ld e, a
- ld d, a
-__I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL)
- ; to a Floating Point Number returned in (A ED CB)
- ld a, d
- or a ; Test sign
- jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned
- call __NEG32 ; Convert it to positive
- call __U32TOFREG ; Convert it to Floating point
- set 7, e ; Put the sign bit (negative) in the 31bit of mantissa
- ret
-__U8TOFREG:
- ; Converts an unsigned 8 bit (A) to Floating point
- ld l, a
- ld h, 0
- ld e, h
- ld d, h
-__U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL)
- ; to a Floating point number returned in A ED CB
- PROC
- LOCAL __U32TOFREG_END
- ld a, d
- or e
- or h
- or l
- ld b, d
- ld c, e ; Returns 00 0000 0000 if ZERO
- ret z
- push de
- push hl
- exx
- pop de ; Loads integer into B'C' D'E'
- pop bc
- exx
- ld l, 128 ; Exponent
- ld bc, 0 ; DEBC = 0
- ld d, b
- ld e, c
-__U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG
- exx
- ld a, d ; B'C'D'E' == 0 ?
- or e
- or b
- or c
- jp z, __U32TOFREG_END ; We are done
- srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry
- rr c
- rr d
- rr e
- exx
- rr e ; Shift EDCB >> 1, inserting the carry on the left
- rr d
- rr c
- rr b
- inc l ; Increment exponent
- jp __U32TOFREG_LOOP
-__U32TOFREG_END:
- exx
- ld a, l ; Puts the exponent in a
- res 7, e ; Sets the sign bit to 0 (positive)
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm"
- push namespace core
-__F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL)
- ; to a Floating Point Number returned in (C ED CB)
- PROC
- LOCAL __F16TOFREG2
- ld a, d
- or a ; Test sign
- jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned
- call __NEG32 ; Convert it to positive
- call __F16TOFREG2 ; Convert it to Floating point
- set 7, e ; Put the sign bit (negative) in the 31bit of mantissa
- ret
-__F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL)
- ; to a Floating point number returned in C DE HL
- ld a, d
- or e
- or h
- or l
- ld b, h
- ld c, l
- ret z ; Return 00 0000 0000 if 0
- push de
- push hl
- exx
- pop de ; Loads integer into B'C' D'E'
- pop bc
- exx
- ld l, 112 ; Exponent
- ld bc, 0 ; DEBC = 0
- ld d, b
- ld e, c
- jp __U32TOFREG_LOOP ; Proceed as an integer
- ENDP
- pop namespace
-#line 28 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
- ;; Updates restore point to the given HL mem. address
- push namespace core
-__RESTORE:
- PROC
- LOCAL __DATA_ADDR
- ld (__DATA_ADDR), hl
- ret
- ;; Reads a value from the DATA mem area and updates __DATA_ADDR ptr to the
- ;; next item. On Out Of Data, restarts
- ;;
-__READ:
- LOCAL read_restart, cont, cont2, table, no_func
- LOCAL dynamic_cast, dynamic_cast2, dynamic_cast3, dynamic_cast4
- LOCAL _decode_table, coerce_to_int, coerce_to_int2, promote_to_i16
- LOCAL _from_i8, _from_u8
- LOCAL _from_i16, _from_u16
- LOCAL _from_i32, _from_u32
- LOCAL _from_fixed, __data_error
- push af ; type of data to read
- ld hl, (__DATA_ADDR)
-read_restart:
- ld a, (hl)
- or a ; 0 => OUT of data
- jr nz, cont
- ;; Signals out of data
- ld hl, .DATA.__DATA__0
- ld (__DATA_ADDR), hl
- jr read_restart ; Start again
-cont:
- and 0x80
- ld a, (hl)
- push af
- jp z, no_func ;; Loads data directly, not a function
- inc hl
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld (__DATA_ADDR), hl ;; Store address of next DATA
- ex de, hl
-cont2:
- ld de, dynamic_cast
- push de ; ret address
- jp (hl) ; "call (hl)"
- ;; Now tries to convert the given result to the expected type or raise an error
-dynamic_cast:
- exx
- ex af, af'
- pop af ; type READ
- and 0x7F ; clear bit 7
- pop hl ; type requested by USER (type of the READ variable)
- ld c, h ; save requested type (save it in register C)
- cp h
- exx
- jr nz, dynamic_cast2 ; Types are identical?
- ;; yes, they are
- ex af, af'
- ret
-dynamic_cast2:
- cp 1 ; Requested a number, but read a string?
- jr nz, dynamic_cast3
- call __MEM_FREE ; Frees str from memory
- jr __data_error
-dynamic_cast3:
- exx
- ld b, a ; Read type
- ld a, c ; Requested type
- cp 1
- jr z, __data_error
- cp b
- jr c, dynamic_cast4
- ;; here the user expected type is "larger" than the read one
- ld a, b
- sub 2
- add a, a
- ld l, a
- ld h, 0
- ld de, _decode_table
- add hl, de
- ld e, (hl)
- inc hl
- ld h, (hl)
- ld l, e
- push hl
- ld a, c ; Requested type
- exx
- ret
-__data_error:
- ;; When a data is read, but cannot be converted to the requested type
- ;; that is, the user asked for a string and we read a number or vice versa
- ld a, ERROR_InvalidArg
- call __STOP ; The user expected a string, but read a number
- xor a
- ld h, a
- ld l, a
- ld e, a
- ld d, a
- ld b, a
- ld c, a
- ret
-_decode_table:
- dw _from_i8
- dw _from_u8
- dw _from_i16
- dw _from_u16
- dw _from_i32
- dw _from_u32
- dw _from_fixed
-_from_i8:
- cp 4
- jr nc, promote_to_i16
- ex af, af'
- ret ;; Was from Byte to Ubyte
-promote_to_i16:
- ex af, af'
- ld l, a
- rla
- sbc a, a
- ld h, a ; copy sgn to h
- ex af, af'
- jr _before_from_i16
-_from_u8:
- ex af, af'
- ld l, a
- ld h, 0
- ex af, af'
- ;; Promoted to i16
-_before_from_i16:
-_from_i16:
- cp 6
- ret c ;; from i16 to u16
- ;; Promote i16 to i32
- ex af, af'
- ld a, h
- rla
- sbc a, a
- ld e, a
- ld d, a
- ex af, af'
-_from_i32:
- cp 7
- ret z ;; From i32 to u32
- ret c ;; From u16 to i32
- cp 9
- jp z, __I32TOFREG
-_from_u32:
- cp 9
- jp z, __U32TOFREG
- ex de, hl
- ld hl, 0
- cp 8
- ret z
-_from_fixed: ;; From fixed to float
- jp __F16TOFREG
-_from_u16:
- ld de, 0 ; HL 0x0000 => 32 bits
- jp _from_i32
-dynamic_cast4:
- ;; The user type is "shorter" than the read one
- cp 8 ;; required type
- jr c, before_to_int ;; required < fixed (f16)
- ex af, af'
- exx ;; Ok, we must convert from float to f16
- jp __FTOF16REG
-before_to_int:
- ld a, b ;; read type
- cp 8 ;;
- jr c, coerce_to_int2
- jr nz, coerce_to_int ;; From float to int
- ld a, c ;; user type
- exx
- ;; f16 to Long
- ex de, hl
- ld a, h
- rla
- sbc a, a
- ld d, a
- ld e, a
- exx
- jr coerce_to_int2
-coerce_to_int:
- exx
- ex af, af'
- call __FTOU32REG
- ex af, af' ; a contains user type
- exx
-coerce_to_int2: ; At this point we have an u/integer in hl
- exx
- cp 4
- ret nc ; Already done. Return the result
- ld a, l ; Truncate to byte
- ret
-no_func:
- exx
- ld de, dynamic_cast
- push de ; Ret address
- dec a ; 0 => string; 1, 2 => byte; 3, 4 => integer; 5, 6 => long, 7 => fixed; 8 => float
- ld h, 0
- add a, a
- ld l, a
- ld de, table
- add hl, de
- ld e, (hl)
- inc hl
- ld h, (hl)
- ld l, e
- push hl ; address to jump to
- exx
- inc hl
- ret ; jp (sp) => jump to table[a - 1]
-table:
- LOCAL __01_decode_string
- LOCAL __02_decode_byte
- LOCAL __03_decode_ubyte
- LOCAL __04_decode_integer
- LOCAL __05_decode_uinteger
- LOCAL __06_decode_long
- LOCAL __07_decode_ulong
- LOCAL __08_decode_fixed
- LOCAL __09_decode_float
- ;; 1 -> Decode string
- ;; 2, 3 -> Decode Byte, UByte
- ;; 4, 5 -> Decode Integer, UInteger
- ;; 6, 7 -> Decode Long, ULong
- ;; 8 -> Decode Fixed
- ;; 9 -> Decode Float
- dw __01_decode_string
- dw __02_decode_byte
- dw __03_decode_ubyte
- dw __04_decode_integer
- dw __05_decode_uinteger
- dw __06_decode_long
- dw __07_decode_ulong
- dw __08_decode_fixed
- dw __09_decode_float
-__01_decode_string:
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld (__DATA_ADDR), hl ;; Store address of next DATA
- ex de, hl
- jp __LOADSTR
-__02_decode_byte:
-__03_decode_ubyte:
- ld a, (hl)
- inc hl
- ld (__DATA_ADDR), hl
- ret
-__04_decode_integer:
-__05_decode_uinteger:
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld (__DATA_ADDR), hl
- ex de, hl
- ret
-__06_decode_long:
-__07_decode_ulong:
-__08_decode_fixed:
- ld b, h
- ld c, l
- inc bc
- inc bc
- inc bc
- inc bc
- ld (__DATA_ADDR), bc
- jp __ILOAD32
-__09_decode_float:
- call __LOADF
- inc hl
- ld (__DATA_ADDR), hl
- ld h, a ; returns A in H; sets A free
- ret
-__DATA_ADDR: ;; Stores current DATA ptr
- dw .DATA.__DATA__0
- ENDP
- pop namespace
-#line 125 "arch/zx48k/read10.bas"
- END
diff --git a/tests/functional/arch/zx48k/read5.asm b/tests/functional/arch/zx48k/read5.asm
deleted file mode 100644
index 35ce4c0b1..000000000
--- a/tests/functional/arch/zx48k/read5.asm
+++ /dev/null
@@ -1,2327 +0,0 @@
- org 32768
-.core.__START_PROGRAM:
- di
- push ix
- push iy
- exx
- push hl
- exx
- ld hl, 0
- add hl, sp
- ld (.core.__CALL_BACK__), hl
- ei
- call .core.__MEM_INIT
- call .core.__PRINT_INIT
- jp .core.__MAIN_PROGRAM__
-.core.__CALL_BACK__:
- DEFW 0
-.core.ZXBASIC_USER_DATA:
- ; Defines HEAP SIZE
-.core.ZXBASIC_HEAP_SIZE EQU 4768
-.core.ZXBASIC_MEM_HEAP:
- DEFS 4768
- ; Defines USER DATA Length in bytes
-.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
- .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
- .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
-_v:
- DEFB 81h
- DEFB 40h
- DEFB 00h
- DEFB 00h
- DEFB 00h
-_c:
- DEFB 00, 00, 00, 00, 00
-_d:
- DEFB 00, 00, 00, 00, 00
-_i:
- DEFB 00
-.core.ZXBASIC_USER_DATA_END:
-.core.__MAIN_PROGRAM__:
- ld hl, .DATA.__DATA__0
- call .core.__RESTORE
- ld a, 1
- ld (_i), a
- jp .LABEL.__LABEL0
-.LABEL.__LABEL3:
- ld a, 9
- call .core.__READ
- ld hl, _c
- call .core.__STOREF
- ld a, 9
- call .core.__READ
- ld hl, _d
- call .core.__STOREF
- call .core.COPY_ATTR
- ld a, (_c)
- ld de, (_c + 1)
- ld bc, (_c + 3)
- call .core.__PRINTF
- call .core.PRINT_COMMA
- ld a, (_d)
- ld de, (_d + 1)
- ld bc, (_d + 3)
- call .core.__PRINTF
- call .core.PRINT_EOL
-.LABEL.__LABEL4:
- ld hl, _i
- inc (hl)
-.LABEL.__LABEL0:
- ld a, 4
- ld hl, (_i - 1)
- cp h
- jp nc, .LABEL.__LABEL3
-.LABEL.__LABEL2:
- ld hl, 0
- ld b, h
- ld c, l
-.core.__END_PROGRAM:
- di
- ld hl, (.core.__CALL_BACK__)
- ld sp, hl
- exx
- pop hl
- exx
- pop iy
- pop ix
- ei
- ret
-___DATA__FUNCPTR__0:
- ld a, (_v)
- ld de, (_v + 1)
- ld bc, (_v + 3)
- ld hl, 00000h
- push hl
- ld hl, 00048h
- push hl
- ld h, 085h
- push hl
- call .core.__MULF
-___DATA__FUNCPTR__0__leave:
- ret
-___DATA__FUNCPTR__1:
- ld a, (_v)
- ld de, (_v + 1)
- ld bc, (_v + 3)
- call .core.SIN
- push bc
- push de
- push af
- ld a, (_v)
- ld de, (_v + 1)
- ld bc, (_v + 3)
- call .core.TAN
- push bc
- push de
- push af
- ld a, 082h
- ld de, 00000h
- ld bc, 00000h
- call .core.__POW
- call .core.__MULF
-___DATA__FUNCPTR__1__leave:
- ret
-___DATA__FUNCPTR__2:
- ld a, (_v)
- ld de, (_v + 1)
- ld bc, (_v + 3)
- ld hl, 0A2DAh
- push hl
- ld hl, 00F49h
- push hl
- ld h, 082h
- push hl
- call .core.__MULF
-___DATA__FUNCPTR__2__leave:
- ret
-.DATA.__DATA__0:
- DEFB 3
- DEFB 10
- DEFB 89h
- DEFW ___DATA__FUNCPTR__0
- DEFB 89h
- DEFW ___DATA__FUNCPTR__1
- DEFB 89h
- DEFW ___DATA__FUNCPTR__2
-__DATA__END:
- DEFB 00h
- ;; --- end of user code ---
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/stackf.asm"
- ; -------------------------------------------------------------
- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC
- ; -------------------------------------------------------------
- push namespace core
- __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB)
- __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB)
-__FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4)
- ; Second argument to push into the stack calculator is popped out of the stack
- ; Since the caller routine also receives the parameters into the top of the stack
- ; four bytes must be removed from SP before pop them out
- call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK
- exx
- pop hl ; Caller-Caller return addr
- exx
- pop hl ; Caller return addr
- pop af
- pop de
- pop bc
- push hl ; Caller return addr
- exx
- push hl ; Caller-Caller return addr
- exx
- jp __FPSTACK_PUSH
-__FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK
- ; This format is specified in the ZX 48K Manual
- ; You can push a 16 bit signed integer as
- ; 0 SS LL HH 0, being SS the sign and LL HH the low
- ; and High byte respectively
- ld a, h
- rla ; sign to Carry
- sbc a, a ; 0 if positive, FF if negative
- ld e, a
- ld d, l
- ld c, h
- xor a
- ld b, a
- jp __FPSTACK_PUSH
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf.asm"
- ; -------------------------------------------------------------
- ; Floating point library using the FP ROM Calculator (ZX 48K)
- ; All of them uses A EDCB registers as 1st paramter.
- ; For binary operators, the 2n operator must be pushed into the
- ; stack, in the order A DE BC.
- ;
- ; Uses CALLEE convention
- ; -------------------------------------------------------------
- push namespace core
-__MULF: ; Multiplication
- call __FPSTACK_PUSH2
- ; ------------- ROM MUL
- rst 28h
- defb 04h ;
- defb 38h; ; END CALC
- jp __FPSTACK_POP
- pop namespace
-#line 110 "arch/zx48k/read5.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
- ;; -----------------------------------------------------------------------
- ;; ZX Basic System Vars
- ;; Some of them will be mapped over Sinclair ROM ones for compatibility
- ;; -----------------------------------------------------------------------
- push namespace core
-SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer)
-SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.)
- ; These are mapped onto ZX Spectrum ROM VARS
- CHARS EQU 23606 ; Pointer to ROM/RAM Charset
- TV_FLAG EQU 23612 ; Flags for controlling output to screen
- UDG EQU 23675 ; Pointer to UDG Charset
- COORDS EQU 23677 ; Last PLOT coordinates
- FLAGS2 EQU 23681 ;
- ECHO_E EQU 23682 ;
- DFCC EQU 23684 ; Next screen addr for PRINT
- DFCCL EQU 23686 ; Next screen attr for PRINT
- S_POSN EQU 23688
- ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands
- ATTR_T EQU 23695 ; temporary ATTRIBUTES
- P_FLAG EQU 23697 ;
- MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars
- SCR_COLS EQU 33 ; Screen with in columns + 1
- SCR_ROWS EQU 24 ; Screen height in rows
- SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 111 "arch/zx48k/read5.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm"
- ; -------------------------------------------------------------
- ; Floating point library using the FP ROM Calculator (ZX 48K)
- ; All of them uses A EDCB registers as 1st paramter.
- ; For binary operators, the 2n operator must be pushed into the
- ; stack, in the order A DE BC.
- ;
- ; Uses CALLEE convention
- ;
-; Operands comes swapped:
- ; 1 st parameter is the BASE (A ED CB)
- ; 2 nd parameter (Top of the stack) is Exponent
- ; -------------------------------------------------------------
- push namespace core
-__POW: ; Exponentiation
- PROC
- call __FPSTACK_PUSH2
- ; ------------- ROM POW
- rst 28h
- defb 01h ; Exchange => 1, Base
- defb 06h ; POW
- defb 38h; ; END CALC
- jp __FPSTACK_POP
- ENDP
- pop namespace
-#line 112 "arch/zx48k/read5.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm"
- push namespace core
-SIN: ; Computes SIN using ROM FP-CALC
- call __FPSTACK_PUSH
- rst 28h ; ROM CALC
- defb 1Fh
- defb 38h ; END CALC
- jp __FPSTACK_POP
- pop namespace
-#line 113 "arch/zx48k/read5.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm"
- push namespace core
-TAN: ; Computes TAN using ROM FP-CALC
- call __FPSTACK_PUSH
- rst 28h ; ROM CALC
- defb 21h ; TAN
- defb 38h ; END CALC
- jp __FPSTACK_POP
- pop namespace
-#line 114 "arch/zx48k/read5.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printf.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
- ; ---------------------------------------------------------------------
- ; __MEM_INIT must be called to initalize this library with the
- ; standard parameters
- ; ---------------------------------------------------------------------
- push namespace core
-__MEM_INIT: ; Initializes the library using (RAMTOP) as start, and
- ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start
- ld de, ZXBASIC_HEAP_SIZE ; Change this with your size
- ; ---------------------------------------------------------------------
- ; __MEM_INIT2 initalizes this library
-; Parameters:
-; HL : Memory address of 1st byte of the memory heap
-; DE : Length in bytes of the Memory Heap
- ; ---------------------------------------------------------------------
-__MEM_INIT2:
- ; HL as TOP
- PROC
- dec de
- dec de
- dec de
- dec de ; DE = length - 4; HL = start
- ; This is done, because we require 4 bytes for the empty dummy-header block
- xor a
- ld (hl), a
- inc hl
- ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4
- inc hl
- ld b, h
- ld c, l
- inc bc
- inc bc ; BC = starts of next block
- ld (hl), c
- inc hl
- ld (hl), b
- inc hl ; Pointer to next block
- ld (hl), e
- inc hl
- ld (hl), d
- inc hl ; Block size (should be length - 4 at start); This block contains all the available memory
- ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block)
- inc hl
- ld (hl), a
- ld a, 201
- ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again
- ret
- ENDP
- pop namespace
-#line 69 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
- ; ---------------------------------------------------------------------
- ; MEM_FREE
- ; Frees a block of memory
- ;
-; Parameters:
- ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing
- ; is done
- ; ---------------------------------------------------------------------
- push namespace core
-MEM_FREE:
-__MEM_FREE: ; Frees the block pointed by HL
- ; HL DE BC & AF modified
- PROC
- LOCAL __MEM_LOOP2
- LOCAL __MEM_LINK_PREV
- LOCAL __MEM_JOIN_TEST
- LOCAL __MEM_BLOCK_JOIN
- ld a, h
- or l
- ret z ; Return if NULL pointer
- dec hl
- dec hl
- ld b, h
- ld c, l ; BC = Block pointer
- ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start
-__MEM_LOOP2:
- inc hl
- inc hl ; Next block ptr
- ld e, (hl)
- inc hl
- ld d, (hl) ; Block next ptr
- ex de, hl ; DE = &(block->next); HL = block->next
- ld a, h ; HL == NULL?
- or l
- jp z, __MEM_LINK_PREV; if so, link with previous
- or a ; Clear carry flag
- sbc hl, bc ; Carry if BC > HL => This block if before
- add hl, bc ; Restores HL, preserving Carry flag
- jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block
- ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next
-__MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL
- ex de, hl
- push hl
- dec hl
- ld (hl), c
- inc hl
- ld (hl), b ; (DE) <- BC
- ld h, b ; HL <- BC (Free block ptr)
- ld l, c
- inc hl ; Skip block length (2 bytes)
- inc hl
- ld (hl), e ; Block->next = DE
- inc hl
- ld (hl), d
- ; --- LINKED ; HL = &(BC->next) + 2
- call __MEM_JOIN_TEST
- pop hl
-__MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them
- ; hl = Ptr to current block + 2
- ld d, (hl)
- dec hl
- ld e, (hl)
- dec hl
- ld b, (hl) ; Loads block length into BC
- dec hl
- ld c, (hl) ;
- push hl ; Saves it for later
- add hl, bc ; Adds its length. If HL == DE now, it must be joined
- or a
- sbc hl, de ; If Z, then HL == DE => We must join
- pop hl
- ret nz
-__MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC
- push hl ; Saves it for later
- ex de, hl
- ld e, (hl) ; DE -> block->next->length
- inc hl
- ld d, (hl)
- inc hl
- ex de, hl ; DE = &(block->next)
- add hl, bc ; HL = Total Length
- ld b, h
- ld c, l ; BC = Total Length
- ex de, hl
- ld e, (hl)
- inc hl
- ld d, (hl) ; DE = block->next
- pop hl ; Recovers Pointer to block
- ld (hl), c
- inc hl
- ld (hl), b ; Length Saved
- inc hl
- ld (hl), e
- inc hl
- ld (hl), d ; Next saved
- ret
- ENDP
- pop namespace
-#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm"
- ; PRINT command routine
- ; Prints string pointed by HL
- push namespace core
-PRINT_STR:
-__PRINTSTR: ; __FASTCALL__ Entry to print_string
- PROC
- LOCAL __PRINT_STR_LOOP
- LOCAL __PRINT_STR_END
- ld d, a ; Saves A reg (Flag) for later
- ld a, h
- or l
- ret z ; Return if the pointer is NULL
- push hl
- ld c, (hl)
- inc hl
- ld b, (hl)
- inc hl ; BC = LEN(a$); HL = &a$
-__PRINT_STR_LOOP:
- ld a, b
- or c
- jr z, __PRINT_STR_END ; END if BC (counter = 0)
- ld a, (hl)
- call __PRINTCHAR
- inc hl
- dec bc
- jp __PRINT_STR_LOOP
-__PRINT_STR_END:
- pop hl
- ld a, d ; Recovers A flag
- or a ; If not 0 this is a temporary string. Free it
- ret z
- jp __MEM_FREE ; Frees str from heap and return from there
-__PRINT_STR:
- ; Fastcall Entry
- ; It ONLY prints strings
- ; HL = String start
- ; BC = String length (Number of chars)
- push hl ; Push str address for later
- ld d, a ; Saves a FLAG
- jp __PRINT_STR_LOOP
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printf.asm"
- push namespace core
-__PRINTF: ; Prints a Fixed point Number stored in C ED LH
- PROC
- LOCAL RECLAIM2
- LOCAL STK_END
- STK_END EQU 5C65h
- ld hl, (ATTR_T)
- push hl ; Saves ATTR_T since BUG ROM changes it
- ld hl, (STK_END)
- push hl ; Stores STK_END
- call __FPSTACK_PUSH ; Push number into stack
- rst 28h ; # Rom Calculator
- defb 2Eh ; # STR$(x)
- defb 38h ; # END CALC
- call __FPSTACK_POP ; Recovers string parameters to A ED CB
- pop hl
- ld (STK_END), hl ; Balance STK_END to avoid STR$ bug
- pop hl
- ld (ATTR_T), hl ; Restores ATTR_T
- ex de, hl ; String position now in HL
- push bc
- xor a ; Avoid the str to be FREED from heap
- call __PRINT_STR
- pop bc
- inc bc
- jp RECLAIM2 ; Frees TMP Memory
- RECLAIM2 EQU 19E8h
- ENDP
- pop namespace
-#line 116 "arch/zx48k/read5.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
- ;; This implements READ & RESTORE functions
- ;; Reads a new element from the DATA Address code
- ;; Updates the DATA_ADDR read ptr for the next read
- ;; Data codification is 1 byte for type followed by data bytes
- ;; Byte type is encoded as follows
-;; 00: End of data
-;; 01: String
-;; 02: Byte
-;; 03: Ubyte
-;; 04: Integer
-;; 05: UInteger
-;; 06: Long
-;; 07: ULong
-;; 08: Fixed
-;; 09: Float
- ;; bit7 is set for a parameter-less function
- ;; In that case, the next two bytes are the ptr of the function to jump
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the MIT license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the MIT license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be freed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
- ; ---------------------------------------------------------------------
- ; MEM_ALLOC
- ; Allocates a block of memory in the heap.
- ;
- ; Parameters
- ; BC = Length of requested memory block
- ;
-; Returns:
- ; HL = Pointer to the allocated block in memory. Returns 0 (NULL)
- ; if the block could not be allocated (out of memory)
- ; ---------------------------------------------------------------------
- push namespace core
-MEM_ALLOC:
-__MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC)
- PROC
- LOCAL __MEM_LOOP
- LOCAL __MEM_DONE
- LOCAL __MEM_SUBTRACT
- LOCAL __MEM_START
- LOCAL TEMP, TEMP0
- TEMP EQU TEMP0 + 1
- ld hl, 0
- ld (TEMP), hl
-__MEM_START:
- ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start
- inc bc
- inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer
-__MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE
- ld a, h ; HL = NULL (No memory available?)
- or l
-#line 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm"
- ret z ; NULL
-#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm"
- ; HL = Pointer to Free block
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl ; DE = Block Length
- push hl ; HL = *pointer to -> next block
- ex de, hl
- or a ; CF = 0
- sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length)
- jp nc, __MEM_DONE
- pop hl
- ld (TEMP), hl
- ex de, hl
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
- jp __MEM_LOOP
-__MEM_DONE: ; A free block has been found.
- ; Check if at least 4 bytes remains free (HL >= 4)
- push hl
- exx ; exx to preserve bc
- pop hl
- ld bc, 4
- or a
- sbc hl, bc
- exx
- jp nc, __MEM_SUBTRACT
- ; At this point...
- ; less than 4 bytes remains free. So we return this block entirely
- ; We must link the previous block with the next to this one
- ; (DE) => Pointer to next block
- ; (TEMP) => &(previous->next)
- pop hl ; Discard current block pointer
- push de
- ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a ; HL = (HL)
- ex de, hl ; HL = Previous block pointer; DE = Next block pointer
-TEMP0:
- ld hl, 0 ; Pre-previous block pointer
- ld (hl), e
- inc hl
- ld (hl), d ; LINKED
- pop hl ; Returning block.
- ret
-__MEM_SUBTRACT:
- ; At this point we have to store HL value (Length - BC) into (DE - 2)
- ex de, hl
- dec hl
- ld (hl), d
- dec hl
- ld (hl), e ; Store new block length
- add hl, de ; New length + DE => free-block start
- pop de ; Remove previous HL off the stack
- ld (hl), c ; Store length on its 1st word
- inc hl
- ld (hl), b
- inc hl ; Return hl
- ret
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm"
- ; Loads a string (ptr) from HL
- ; and duplicates it on dynamic memory again
- ; Finally, it returns result pointer in HL
- push namespace core
-__ILOADSTR: ; This is the indirect pointer entry HL = (HL)
- ld a, h
- or l
- ret z
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a
-__LOADSTR: ; __FASTCALL__ entry
- ld a, h
- or l
- ret z ; Return if NULL
- ld c, (hl)
- inc hl
- ld b, (hl)
- dec hl ; BC = LEN(a$)
- inc bc
- inc bc ; BC = LEN(a$) + 2 (two bytes for length)
- push hl
- push bc
- call __MEM_ALLOC
- pop bc ; Recover length
- pop de ; Recover origin
- ld a, h
- or l
- ret z ; Return if NULL (No memory)
- ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE
- push de ; Saves destiny start
- ldir ; Copies string (length number included)
- pop hl ; Recovers destiny in hl as result
- ret
- pop namespace
-#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iload32.asm"
- ; __FASTCALL__ routine which
- ; loads a 32 bits integer into DE,HL
- ; stored at position pointed by POINTER HL
- ; DE,HL <-- (HL)
- push namespace core
-__ILOAD32:
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a
- ex de, hl
- ret
- pop namespace
-#line 25 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iloadf.asm"
- ; __FASTCALL__ routine which
- ; loads a 40 bits floating point into A ED CB
- ; stored at position pointed by POINTER HL
- ;A DE, BC <-- ((HL))
- push namespace core
-__ILOADF:
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a
- ; __FASTCALL__ routine which
- ; loads a 40 bits floating point into A ED CB
- ; stored at position pointed by POINTER HL
- ;A DE, BC <-- (HL)
-__LOADF: ; Loads a 40 bits FP number from address pointed by HL
- ld a, (hl)
- inc hl
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld c, (hl)
- inc hl
- ld b, (hl)
- ret
- pop namespace
-#line 26 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm"
- push namespace core
-__ABS32:
- bit 7, d
- ret z
-__NEG32: ; Negates DEHL (Two's complement)
- ld a, l
- cpl
- ld l, a
- ld a, h
- cpl
- ld h, a
- ld a, e
- cpl
- ld e, a
- ld a, d
- cpl
- ld d, a
- inc l
- ret nz
- inc h
- ret nz
- inc de
- ret
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm"
- push namespace core
-__FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed)
- ; Input FP number in A EDCB (A exponent, EDCB mantissa)
- ; Output: DEHL 32 bit number (signed)
- PROC
- LOCAL __IS_FLOAT
- LOCAL __NEGATE
- or a
- jr nz, __IS_FLOAT
- ; Here if it is a ZX ROM Integer
- ld h, c
- ld l, d
- ld d, e
- ret
-__IS_FLOAT: ; Jumps here if it is a true floating point number
- ld h, e
- push hl ; Stores it for later (Contains Sign in H)
- push de
- push bc
- exx
- pop de ; Loads mantissa into C'B' E'D'
- pop bc ;
- set 7, c ; Highest mantissa bit is always 1
- exx
- ld hl, 0 ; DEHL = 0
- ld d, h
- ld e, l
- ;ld a, c ; Get exponent
- sub 128 ; Exponent -= 128
- jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128)
- jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0)
- ld b, a ; Loop counter = exponent - 128
-__FTOU32REG_LOOP:
- exx ; Shift C'B' E'D' << 1, output bit stays in Carry
- sla d
- rl e
- rl b
- rl c
- exx ; Shift DEHL << 1, inserting the carry on the right
- rl l
- rl h
- rl e
- rl d
- djnz __FTOU32REG_LOOP
-__FTOU32REG_END:
- pop af ; Take the sign bit
- or a ; Sets SGN bit to 1 if negative
- jp m, __NEGATE ; Negates DEHL
- ret
-__NEGATE:
- exx
- ld a, d
- or e
- or b
- or c
- exx
- jr z, __END
- inc l
- jr nz, __END
- inc h
- jr nz, __END
- inc de
- LOCAL __END
-__END:
- jp __NEG32
- ENDP
-__FTOU8: ; Converts float in C ED LH to Unsigned byte in A
- call __FTOU32REG
- ld a, l
- ret
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm"
- push namespace core
-__FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal
- ; Input FP number in A EDCB (A exponent, EDCB mantissa)
- ld l, a ; Saves exponent for later
- or d
- or e
- or b
- or c
- ld h, e
- ret z ; Return if ZERO
- push hl ; Stores it for later (Contains sign in H, exponent in L)
- push de
- push bc
- exx
- pop de ; Loads mantissa into C'B' E'D'
- pop bc ;
- set 7, c ; Highest mantissa bit is always 1
- exx
- ld hl, 0 ; DEHL = 0
- ld d, h
- ld e, l
- pop bc
- ld a, c ; Get exponent
- sub 112 ; Exponent -= 128 + 16
- push bc ; Saves sign in b again
- jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128)
- jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0)
- ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more)
- jp __FTOU32REG_LOOP ; proceed as an u32 integer
- pop namespace
-#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm"
- push namespace core
-__I8TOFREG:
- ld l, a
- rlca
- sbc a, a ; A = SGN(A)
- ld h, a
- ld e, a
- ld d, a
-__I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL)
- ; to a Floating Point Number returned in (A ED CB)
- ld a, d
- or a ; Test sign
- jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned
- call __NEG32 ; Convert it to positive
- call __U32TOFREG ; Convert it to Floating point
- set 7, e ; Put the sign bit (negative) in the 31bit of mantissa
- ret
-__U8TOFREG:
- ; Converts an unsigned 8 bit (A) to Floating point
- ld l, a
- ld h, 0
- ld e, h
- ld d, h
-__U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL)
- ; to a Floating point number returned in A ED CB
- PROC
- LOCAL __U32TOFREG_END
- ld a, d
- or e
- or h
- or l
- ld b, d
- ld c, e ; Returns 00 0000 0000 if ZERO
- ret z
- push de
- push hl
- exx
- pop de ; Loads integer into B'C' D'E'
- pop bc
- exx
- ld l, 128 ; Exponent
- ld bc, 0 ; DEBC = 0
- ld d, b
- ld e, c
-__U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG
- exx
- ld a, d ; B'C'D'E' == 0 ?
- or e
- or b
- or c
- jp z, __U32TOFREG_END ; We are done
- srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry
- rr c
- rr d
- rr e
- exx
- rr e ; Shift EDCB >> 1, inserting the carry on the left
- rr d
- rr c
- rr b
- inc l ; Increment exponent
- jp __U32TOFREG_LOOP
-__U32TOFREG_END:
- exx
- ld a, l ; Puts the exponent in a
- res 7, e ; Sets the sign bit to 0 (positive)
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm"
- push namespace core
-__F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL)
- ; to a Floating Point Number returned in (C ED CB)
- PROC
- LOCAL __F16TOFREG2
- ld a, d
- or a ; Test sign
- jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned
- call __NEG32 ; Convert it to positive
- call __F16TOFREG2 ; Convert it to Floating point
- set 7, e ; Put the sign bit (negative) in the 31bit of mantissa
- ret
-__F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL)
- ; to a Floating point number returned in C DE HL
- ld a, d
- or e
- or h
- or l
- ld b, h
- ld c, l
- ret z ; Return 00 0000 0000 if 0
- push de
- push hl
- exx
- pop de ; Loads integer into B'C' D'E'
- pop bc
- exx
- ld l, 112 ; Exponent
- ld bc, 0 ; DEBC = 0
- ld d, b
- ld e, c
- jp __U32TOFREG_LOOP ; Proceed as an integer
- ENDP
- pop namespace
-#line 28 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
-#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm"
- ;; Updates restore point to the given HL mem. address
- push namespace core
-__RESTORE:
- PROC
- LOCAL __DATA_ADDR
- ld (__DATA_ADDR), hl
- ret
- ;; Reads a value from the DATA mem area and updates __DATA_ADDR ptr to the
- ;; next item. On Out Of Data, restarts
- ;;
-__READ:
- LOCAL read_restart, cont, cont2, table, no_func
- LOCAL dynamic_cast, dynamic_cast2, dynamic_cast3, dynamic_cast4
- LOCAL _decode_table, coerce_to_int, coerce_to_int2, promote_to_i16
- LOCAL _from_i8, _from_u8
- LOCAL _from_i16, _from_u16
- LOCAL _from_i32, _from_u32
- LOCAL _from_fixed, __data_error
- push af ; type of data to read
- ld hl, (__DATA_ADDR)
-read_restart:
- ld a, (hl)
- or a ; 0 => OUT of data
- jr nz, cont
- ;; Signals out of data
- ld hl, .DATA.__DATA__0
- ld (__DATA_ADDR), hl
- jr read_restart ; Start again
-cont:
- and 0x80
- ld a, (hl)
- push af
- jp z, no_func ;; Loads data directly, not a function
- inc hl
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld (__DATA_ADDR), hl ;; Store address of next DATA
- ex de, hl
-cont2:
- ld de, dynamic_cast
- push de ; ret address
- jp (hl) ; "call (hl)"
- ;; Now tries to convert the given result to the expected type or raise an error
-dynamic_cast:
- exx
- ex af, af'
- pop af ; type READ
- and 0x7F ; clear bit 7
- pop hl ; type requested by USER (type of the READ variable)
- ld c, h ; save requested type (save it in register C)
- cp h
- exx
- jr nz, dynamic_cast2 ; Types are identical?
- ;; yes, they are
- ex af, af'
- ret
-dynamic_cast2:
- cp 1 ; Requested a number, but read a string?
- jr nz, dynamic_cast3
- call __MEM_FREE ; Frees str from memory
- jr __data_error
-dynamic_cast3:
- exx
- ld b, a ; Read type
- ld a, c ; Requested type
- cp 1
- jr z, __data_error
- cp b
- jr c, dynamic_cast4
- ;; here the user expected type is "larger" than the read one
- ld a, b
- sub 2
- add a, a
- ld l, a
- ld h, 0
- ld de, _decode_table
- add hl, de
- ld e, (hl)
- inc hl
- ld h, (hl)
- ld l, e
- push hl
- ld a, c ; Requested type
- exx
- ret
-__data_error:
- ;; When a data is read, but cannot be converted to the requested type
- ;; that is, the user asked for a string and we read a number or vice versa
- ld a, ERROR_InvalidArg
- call __STOP ; The user expected a string, but read a number
- xor a
- ld h, a
- ld l, a
- ld e, a
- ld d, a
- ld b, a
- ld c, a
- ret
-_decode_table:
- dw _from_i8
- dw _from_u8
- dw _from_i16
- dw _from_u16
- dw _from_i32
- dw _from_u32
- dw _from_fixed
-_from_i8:
- cp 4
- jr nc, promote_to_i16
- ex af, af'
- ret ;; Was from Byte to Ubyte
-promote_to_i16:
- ex af, af'
- ld l, a
- rla
- sbc a, a
- ld h, a ; copy sgn to h
- ex af, af'
- jr _before_from_i16
-_from_u8:
- ex af, af'
- ld l, a
- ld h, 0
- ex af, af'
- ;; Promoted to i16
-_before_from_i16:
-_from_i16:
- cp 6
- ret c ;; from i16 to u16
- ;; Promote i16 to i32
- ex af, af'
- ld a, h
- rla
- sbc a, a
- ld e, a
- ld d, a
- ex af, af'
-_from_i32:
- cp 7
- ret z ;; From i32 to u32
- ret c ;; From u16 to i32
- cp 9
- jp z, __I32TOFREG
-_from_u32:
- cp 9
- jp z, __U32TOFREG
- ex de, hl
- ld hl, 0
- cp 8
- ret z
-_from_fixed: ;; From fixed to float
- jp __F16TOFREG
-_from_u16:
- ld de, 0 ; HL 0x0000 => 32 bits
- jp _from_i32
-dynamic_cast4:
- ;; The user type is "shorter" than the read one
- cp 8 ;; required type
- jr c, before_to_int ;; required < fixed (f16)
- ex af, af'
- exx ;; Ok, we must convert from float to f16
- jp __FTOF16REG
-before_to_int:
- ld a, b ;; read type
- cp 8 ;;
- jr c, coerce_to_int2
- jr nz, coerce_to_int ;; From float to int
- ld a, c ;; user type
- exx
- ;; f16 to Long
- ex de, hl
- ld a, h
- rla
- sbc a, a
- ld d, a
- ld e, a
- exx
- jr coerce_to_int2
-coerce_to_int:
- exx
- ex af, af'
- call __FTOU32REG
- ex af, af' ; a contains user type
- exx
-coerce_to_int2: ; At this point we have an u/integer in hl
- exx
- cp 4
- ret nc ; Already done. Return the result
- ld a, l ; Truncate to byte
- ret
-no_func:
- exx
- ld de, dynamic_cast
- push de ; Ret address
- dec a ; 0 => string; 1, 2 => byte; 3, 4 => integer; 5, 6 => long, 7 => fixed; 8 => float
- ld h, 0
- add a, a
- ld l, a
- ld de, table
- add hl, de
- ld e, (hl)
- inc hl
- ld h, (hl)
- ld l, e
- push hl ; address to jump to
- exx
- inc hl
- ret ; jp (sp) => jump to table[a - 1]
-table:
- LOCAL __01_decode_string
- LOCAL __02_decode_byte
- LOCAL __03_decode_ubyte
- LOCAL __04_decode_integer
- LOCAL __05_decode_uinteger
- LOCAL __06_decode_long
- LOCAL __07_decode_ulong
- LOCAL __08_decode_fixed
- LOCAL __09_decode_float
- ;; 1 -> Decode string
- ;; 2, 3 -> Decode Byte, UByte
- ;; 4, 5 -> Decode Integer, UInteger
- ;; 6, 7 -> Decode Long, ULong
- ;; 8 -> Decode Fixed
- ;; 9 -> Decode Float
- dw __01_decode_string
- dw __02_decode_byte
- dw __03_decode_ubyte
- dw __04_decode_integer
- dw __05_decode_uinteger
- dw __06_decode_long
- dw __07_decode_ulong
- dw __08_decode_fixed
- dw __09_decode_float
-__01_decode_string:
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld (__DATA_ADDR), hl ;; Store address of next DATA
- ex de, hl
- jp __LOADSTR
-__02_decode_byte:
-__03_decode_ubyte:
- ld a, (hl)
- inc hl
- ld (__DATA_ADDR), hl
- ret
-__04_decode_integer:
-__05_decode_uinteger:
- ld e, (hl)
- inc hl
- ld d, (hl)
- inc hl
- ld (__DATA_ADDR), hl
- ex de, hl
- ret
-__06_decode_long:
-__07_decode_ulong:
-__08_decode_fixed:
- ld b, h
- ld c, l
- inc bc
- inc bc
- inc bc
- inc bc
- ld (__DATA_ADDR), bc
- jp __ILOAD32
-__09_decode_float:
- call __LOADF
- inc hl
- ld (__DATA_ADDR), hl
- ld h, a ; returns A in H; sets A free
- ret
-__DATA_ADDR: ;; Stores current DATA ptr
- dw .DATA.__DATA__0
- ENDP
- pop namespace
-#line 117 "arch/zx48k/read5.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/storef.asm"
- push namespace core
-__PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL)
- push de
- ex de, hl ; DE <- HL
- push ix
- pop hl ; HL <- IX
- add hl, de ; HL <- IX + HL
- pop de
-__ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register
- ex af, af'
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a ; HL = (HL)
- ex af, af'
-__STOREF: ; Stores the given FP number in A EDCB at address HL
- ld (hl), a
- inc hl
- ld (hl), e
- inc hl
- ld (hl), d
- inc hl
- ld (hl), c
- inc hl
- ld (hl), b
- ret
- pop namespace
-#line 118 "arch/zx48k/read5.bas"
- END
diff --git a/tests/functional/arch/zx48k/subrec.asm b/tests/functional/arch/zx48k/subrec.asm
index e78b2c5d9..5e74bb355 100644
--- a/tests/functional/arch/zx48k/subrec.asm
+++ b/tests/functional/arch/zx48k/subrec.asm
@@ -10,16 +10,10 @@
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
- call .core.__MEM_INIT
- call .core.__PRINT_INIT
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
.core.ZXBASIC_USER_DATA:
- ; Defines HEAP SIZE
-.core.ZXBASIC_HEAP_SIZE EQU 4768
-.core.ZXBASIC_MEM_HEAP:
- DEFS 4768
; Defines USER DATA Length in bytes
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
@@ -29,6 +23,8 @@ _result:
DEFB 00h
DEFB 00h
DEFB 00h
+_dummy:
+ DEFB 00, 00, 00, 00
_x:
DEFB 00
.core.ZXBASIC_USER_DATA_END:
@@ -50,19 +46,10 @@ _x:
push de
push hl
call _fact
- call .core.COPY_ATTR
- ld hl, .LABEL.__LABEL5
- xor a
- call .core.__PRINTSTR
- ld a, (_x)
- call .core.__PRINTU8
- ld hl, .LABEL.__LABEL6
- xor a
- call .core.__PRINTSTR
ld hl, (_result)
ld de, (_result + 2)
- call .core.__PRINTU32
- call .core.PRINT_EOL
+ ld (_dummy), hl
+ ld (_dummy + 2), de
.LABEL.__LABEL4:
ld hl, _x
inc (hl)
@@ -100,7 +87,7 @@ _fact:
ld hl, 2
call .core.__SUB32
jp c, _fact__leave
-.LABEL.__LABEL8:
+.LABEL.__LABEL6:
ld l, (ix+4)
ld h, (ix+5)
ld e, (ix+6)
@@ -133,20 +120,6 @@ _fact__leave:
ex (sp), hl
exx
ret
-.LABEL.__LABEL5:
- DEFW 0006h
- DEFB 46h
- DEFB 61h
- DEFB 63h
- DEFB 74h
- DEFB 20h
- DEFB 28h
-.LABEL.__LABEL6:
- DEFW 0004h
- DEFB 29h
- DEFB 20h
- DEFB 3Dh
- DEFB 20h
;; --- end of user code ---
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm"
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/_mul32.asm"
@@ -231,7 +204,7 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL)
ret
pop namespace
f
-#line 117 "arch/zx48k/subrec.bas"
+#line 94 "arch/zx48k/subrec.bas"
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/sub32.asm"
; SUB32
; Perform TOP of the stack - DEHL
@@ -258,7 +231,7 @@ __SUB32:
exx
ret
pop namespace
-#line 118 "arch/zx48k/subrec.bas"
+#line 95 "arch/zx48k/subrec.bas"
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cls.asm"
;; Clears the user screen (24 rows)
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm"
@@ -316,1502 +289,5 @@ CLS:
ret
ENDP
pop namespace
-#line 119 "arch/zx48k/subrec.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-; vim:ts=4:sw=4:et:
- ; PRINT command routine
- ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- ; Attribute routines
-; vim:ts=4:et:sw:
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm"
- ; Simple error control routines
-; vim:ts=4:et:
- push namespace core
- ERR_NR EQU 23610 ; Error code system variable
- ; Error code definitions (as in ZX spectrum manual)
-; Set error code with:
- ; ld a, ERROR_CODE
- ; ld (ERR_NR), a
- ERROR_Ok EQU -1
- ERROR_SubscriptWrong EQU 2
- ERROR_OutOfMemory EQU 3
- ERROR_OutOfScreen EQU 4
- ERROR_NumberTooBig EQU 5
- ERROR_InvalidArg EQU 9
- ERROR_IntOutOfRange EQU 10
- ERROR_NonsenseInBasic EQU 11
- ERROR_InvalidFileName EQU 14
- ERROR_InvalidColour EQU 19
- ERROR_BreakIntoProgram EQU 20
- ERROR_TapeLoadingErr EQU 26
- ; Raises error using RST #8
-__ERROR:
- ld (__ERROR_CODE), a
- rst 8
-__ERROR_CODE:
- nop
- ret
- ; Sets the error system variable, but keeps running.
- ; Usually this instruction if followed by the END intermediate instruction.
-__STOP:
- ld (ERR_NR), a
- ret
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm"
- push namespace core
-__IN_SCREEN:
- ; Returns NO carry if current coords (D, E)
- ; are OUT of the screen limits
- PROC
- LOCAL __IN_SCREEN_ERR
- ld hl, SCR_SIZE
- ld a, e
- cp l
- jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range
- ld a, d
- cp h
- ret c ; Return if carry (OK)
-__IN_SCREEN_ERR:
-__OUT_OF_SCREEN_ERR:
- ; Jumps here if out of screen
- ld a, ERROR_OutOfScreen
- jp __STOP ; Saves error code and exits
- ENDP
- pop namespace
-#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm"
- push namespace core
-__ATTR_ADDR:
- ; calc start address in DE (as (32 * d) + e)
- ; Contributed by Santiago Romero at http://www.speccy.org
- ld h, 0 ; 7 T-States
- ld a, d ; 4 T-States
- ld d, h
- add a, a ; a * 2 ; 4 T-States
- add a, a ; a * 4 ; 4 T-States
- ld l, a ; HL = A * 4 ; 4 T-States
- add hl, hl ; HL = A * 8 ; 15 T-States
- add hl, hl ; HL = A * 16 ; 15 T-States
- add hl, hl ; HL = A * 32 ; 15 T-States
- add hl, de
- ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address
- add hl, de
- ; Return current screen address in HL
- ret
- ; Sets the attribute at a given screen coordinate (D, E).
- ; The attribute is taken from the ATTR_T memory variable
- ; Used by PRINT routines
-SET_ATTR:
- ; Checks for valid coords
- call __IN_SCREEN
- ret nc
- call __ATTR_ADDR
-__SET_ATTR:
- ; Internal __FASTCALL__ Entry used by printing routines
- ; HL contains the address of the ATTR cell to set
- PROC
-__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address
- ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T
- ld a, d
- and (hl)
- ld c, a ; C = current screen color, masked
- ld a, d
- cpl ; Negate mask
- and e ; Mask current attributes
- or c ; Mix them
- ld (hl), a ; Store result in screen
- ret
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm"
- ; Printing positioning library.
- push namespace core
- ; Loads into DE current ROW, COL print position from S_POSN mem var.
-__LOAD_S_POSN:
- PROC
- ld de, (S_POSN)
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- ret
- ENDP
- ; Saves ROW, COL from DE into S_POSN mem var.
-__SAVE_S_POSN:
- PROC
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ld (S_POSN), hl ; saves it again
-__SET_SCR_PTR: ;; Fast
- push de
- call __ATTR_ADDR
- ld (DFCCL), hl
- pop de
- ld a, d
- ld c, a ; Saves it for later
- and 0F8h ; Masks 3 lower bit ; zy
- ld d, a
- ld a, c ; Recovers it
- and 07h ; MOD 7 ; y1
- rrca
- rrca
- rrca
- or e
- ld e, a
- ld hl, (SCREEN_ADDR)
- add hl, de ; HL = Screen address + DE
- ld (DFCC), hl
- ret
- ENDP
- pop namespace
-#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
- push namespace core
-JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
- add a, a
-JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
- ld e, a
- ld d, 0
-JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
- add hl, de
- ld e, (hl)
- inc hl
- ld d, (hl)
- ex de, hl
-CALL_HL:
- jp (hl)
- pop namespace
-#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ink.asm"
- ; Sets ink color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-INK:
- PROC
- LOCAL __SET_INK
- LOCAL __SET_INK2
- ld de, ATTR_P
-__SET_INK:
- cp 8
- jr nz, __SET_INK2
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- or 7 ; Set bits 0,1,2 to enable transparency
- ld (de), a
- ret
-__SET_INK2:
- ; Another entry. This will set the ink color at location pointer by DE
- and 7 ; # Gets color mod 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0F8h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points DE to MASK_T or MASK_P
- ld a, (de)
- and 0F8h ; Reset bits 0,1,2 sign to disable transparency
- ld (de), a ; Store new attr
- ret
- ; Sets the INK color passed in A register in the ATTR_T variable
-INK_TMP:
- ld de, ATTR_T
- jp __SET_INK
- ENDP
- pop namespace
-#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/paper.asm"
- ; Sets paper color in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-PAPER:
- PROC
- LOCAL __SET_PAPER
- LOCAL __SET_PAPER2
- ld de, ATTR_P
-__SET_PAPER:
- cp 8
- jr nz, __SET_PAPER2
- inc de
- ld a, (de)
- or 038h
- ld (de), a
- ret
- ; Another entry. This will set the paper color at location pointer by DE
-__SET_PAPER2:
- and 7 ; # Remove
- rlca
- rlca
- rlca ; a *= 8
- ld b, a ; Saves the color
- ld a, (de)
- and 0C7h ; Clears previous value
- or b
- ld (de), a
- inc de ; Points to MASK_T or MASK_P accordingly
- ld a, (de)
- and 0C7h ; Resets bits 3,4,5
- ld (de), a
- ret
- ; Sets the PAPER color passed in A register in the ATTR_T variable
-PAPER_TMP:
- ld de, ATTR_T
- jp __SET_PAPER
- ENDP
- pop namespace
-#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm"
- ; Sets flash flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-FLASH:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_FLASH:
- ; Another entry. This will set the flash flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x80
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 07Fh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 7, (hl) ;Reset bit 7 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 7, (hl) ;Set bit 7 to enable transparency
- ret
- ; Sets the FLASH flag passed in A register in the ATTR_T variable
-FLASH_TMP:
- ld hl, ATTR_T
- jr __SET_FLASH
- ENDP
- pop namespace
-#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm"
- ; Sets bright flag in ATTR_P permanently
-; Parameter: Paper color in A register
- push namespace core
-BRIGHT:
- ld hl, ATTR_P
- PROC
- LOCAL IS_TR
- LOCAL IS_ZERO
-__SET_BRIGHT:
- ; Another entry. This will set the bright flag at location pointer by DE
- cp 8
- jr z, IS_TR
- ; # Convert to 0/1
- or a
- jr z, IS_ZERO
- ld a, 0x40
-IS_ZERO:
- ld b, a ; Saves the color
- ld a, (hl)
- and 0BFh ; Clears previous value
- or b
- ld (hl), a
- inc hl
- res 6, (hl) ;Reset bit 6 to disable transparency
- ret
-IS_TR: ; transparent
- inc hl ; Points DE to MASK_T or MASK_P
- set 6, (hl) ;Set bit 6 to enable transparency
- ret
- ; Sets the BRIGHT flag passed in A register in the ATTR_T variable
-BRIGHT_TMP:
- ld hl, ATTR_T
- jr __SET_BRIGHT
- ENDP
- pop namespace
-#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/over.asm"
- ; Sets OVER flag in P_FLAG permanently
-; Parameter: OVER flag in bit 0 of A register
- push namespace core
-OVER:
- PROC
- ld c, a ; saves it for later
- and 2
- ld hl, FLAGS2
- res 1, (HL)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 1 bit for permanent
- ld hl, P_FLAG
- res 1, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets OVER flag in P_FLAG temporarily
-OVER_TMP:
- ld c, a ; saves it for later
- and 2 ; gets bit 1; clears carry
- rra
- ld hl, FLAGS2
- res 0, (hl)
- or (hl)
- ld (hl), a
- ld a, c ; Recovers previous value
- and 1
- ld hl, P_FLAG
- res 0, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/inverse.asm"
- ; Sets INVERSE flag in P_FLAG permanently
-; Parameter: INVERSE flag in bit 0 of A register
- push namespace core
-INVERSE:
- PROC
- and 1 ; # Convert to 0/1
- add a, a; # Shift left 3 bits for permanent
- add a, a
- add a, a
- ld hl, P_FLAG
- res 3, (hl)
- or (hl)
- ld (hl), a
- ret
- ; Sets INVERSE flag in P_FLAG temporarily
-INVERSE_TMP:
- and 1
- add a, a
- add a, a; # Shift left 2 bits for temporary
- ld hl, P_FLAG
- res 2, (hl)
- or (hl)
- ld (hl), a
- jp __SET_ATTR_MODE
- ENDP
- pop namespace
-#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bold.asm"
- ; Sets BOLD flag in P_FLAG permanently
-; Parameter: BOLD flag in bit 0 of A register
- push namespace core
-BOLD:
- PROC
- and 1
- rlca
- rlca
- rlca
- ld hl, FLAGS2
- res 3, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets BOLD flag in P_FLAG temporarily
-BOLD_TMP:
- and 1
- rlca
- rlca
- ld hl, FLAGS2
- res 2, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/italic.asm"
- ; Sets ITALIC flag in P_FLAG permanently
-; Parameter: ITALIC flag in bit 0 of A register
- push namespace core
-ITALIC:
- PROC
- and 1
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 5, (HL)
- or (hl)
- ld (hl), a
- ret
- ; Sets ITALIC flag in P_FLAG temporarily
-ITALIC_TMP:
- and 1
- rrca
- rrca
- rrca
- rrca
- ld hl, FLAGS2
- res 4, (hl)
- or (hl)
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ; Putting a comment starting with @INIT
- ; will make the compiler to add a CALL to
- ; It is useful for initialization routines.
- push namespace core
-__PRINT_INIT: ; To be called before program starts (initializes library)
- PROC
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- ;; Clears ATTR2 flags (OVER 2, etc)
- xor a
- ld (FLAGS2), a
- ld hl, TV_FLAG
- res 0, (hl)
- LOCAL SET_SCR_ADDR
- call __LOAD_S_POSN
- jp __SET_SCR_PTR
- ;; Receives HL = future value of S_POSN
- ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR)
-SET_SCR_ADDR:
- ld (S_POSN), hl
- ex de, hl
- ld hl, SCR_SIZE
- or a
- sbc hl, de
- ex de, hl
- dec e
- jp __SET_SCR_PTR
-__PRINTCHAR: ; Print character store in accumulator (A register)
- ; Modifies H'L', B'C', A'F', D'E', A
- LOCAL PO_GR_1
- LOCAL __PRCHAR
- LOCAL __PRINT_JUMP
- LOCAL __SRCADDR
- LOCAL __PRINT_UDG
- LOCAL __PRGRAPH
- LOCAL __PRINT_START
- PRINT_JUMP_STATE EQU __PRINT_JUMP + 2
-__PRINT_JUMP:
- exx ; Switch to alternative registers
- jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively
-__PRINT_START:
-__PRINT_CHR:
- cp ' '
- jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones
- ex af, af' ; Saves a value (char to print) for later
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- ld l, SCR_COLS - 1
- dec h
- jr nz, 2f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-2:
- call SET_SCR_ADDR
- jr 4f
-1:
- ld (S_POSN), hl
-4:
- ex af, af'
- cp 80h ; Is it a "normal" (printable) char
- jr c, __SRCADDR
- cp 90h ; Is it an UDG?
- jr nc, __PRINT_UDG
- ; Print an 8 bit pattern (80h to 8Fh)
- ld b, a
- call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0
- ld hl, MEM0
- jp __PRGRAPH
- PO_GR_1 EQU 0B38h
-__PRINT_UDG:
- sub 90h ; Sub ASC code
- ld bc, (UDG)
- jr __PRGRAPH0
- __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source
-__SRCADDR:
- ld bc, (CHARS)
-__PRGRAPH0:
- add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org
- ld l, a
- ld h, 0 ; HL = a * 2 (accumulator)
- add hl, hl
- add hl, hl ; HL = a * 8
- add hl, bc ; HL = CHARS address
-__PRGRAPH:
- ex de, hl ; HL = Write Address, DE = CHARS address
- bit 2, (iy + $47)
- call nz, __BOLD
-#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- bit 4, (iy + $47)
- call nz, __ITALIC
-#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- ld hl, (DFCC)
- push hl
- ld b, 8 ; 8 bytes per char
-__PRCHAR:
- ld a, (de) ; DE *must* be source, and HL destiny
-PRINT_MODE: ; Which operation is used to write on the screen
- ; Set it with:
- ; LD A,
- ; LD (PRINT_MODE), A
- ;
- ; Available operations:
- ; NORMAL : 0h --> NOP ; OVER 0
- ; XOR : AEh --> XOR (HL) ; OVER 1
- ; OR : B6h --> OR (HL) ; PUTSPRITE
- ; AND : A6h --> AND (HL) ; PUTMASK
- nop ; Set to one of the values above
-INVERSE_MODE: ; 00 -> NOP -> INVERSE 0
- nop ; 2F -> CPL -> INVERSE 1
- ld (hl), a
- inc de
- inc h ; Next line
- djnz __PRCHAR
- pop hl
- inc hl
- ld (DFCC), hl
- ld hl, (DFCCL) ; current ATTR Pos
- inc hl
- ld (DFCCL), hl
- dec hl
- call __SET_ATTR
- exx
- ret
- ; ------------- SPECIAL CHARS (< 32) -----------------
-__PRINT_SPECIAL: ; Jumps here if it is a special char
- ld hl, __PRINT_TABLE
- jp JUMP_HL_PLUS_2A
-PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence
- exx
-__PRINT_0Dh: ; Called WHEN printing CHR$(13)
- ld hl, (S_POSN)
- dec l
- jr nz, 1f
- dec h
- jr nz, 1f
- inc h
- push hl
- call __SCROLL_SCR
- pop hl
-#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-1:
- ld l, 1
-__PRINT_EOL_END:
- call SET_SCR_ADDR
- exx
- ret
-__PRINT_COM:
- exx
- push hl
- push de
- push bc
- call PRINT_COMMA
- pop bc
- pop de
- pop hl
- ret
-__PRINT_TAB:
- ld hl, __PRINT_TAB1
- jr __PRINT_SET_STATE
-__PRINT_TAB1:
- ld (MEM0), a
- ld hl, __PRINT_TAB2
- jr __PRINT_SET_STATE
-__PRINT_TAB2:
- ld a, (MEM0) ; Load tab code (ignore the current one)
- ld hl, __PRINT_START
- ld (PRINT_JUMP_STATE), hl
- exx
- push hl
- push bc
- push de
- call PRINT_TAB
- pop de
- pop bc
- pop hl
- ret
-__PRINT_AT:
- ld hl, __PRINT_AT1
- jr __PRINT_SET_STATE
-__PRINT_NOP:
-__PRINT_RESTART:
- ld hl, __PRINT_START
-__PRINT_SET_STATE:
- ld (PRINT_JUMP_STATE), hl ; Saves next entry call
- exx
- ret
-__PRINT_AT1: ; Jumps here if waiting for 1st parameter
- ld hl, (S_POSN)
- ld h, a
- ld a, SCR_ROWS
- sub h
- ld (S_POSN + 1), a
- ld hl, __PRINT_AT2
- jr __PRINT_SET_STATE
-__PRINT_AT2:
- call __LOAD_S_POSN
- ld e, a
- call __SAVE_S_POSN
- jr __PRINT_RESTART
-__PRINT_DEL:
- call __LOAD_S_POSN ; Gets current screen position
- dec e
- ld a, -1
- cp e
- jr nz, 3f
- ld e, SCR_COLS - 2
- dec d
- cp d
- jr nz, 3f
- ld d, SCR_ROWS - 1
-3:
- call __SAVE_S_POSN
- exx
- ret
-__PRINT_INK:
- ld hl, __PRINT_INK2
- jr __PRINT_SET_STATE
-__PRINT_INK2:
- call INK_TMP
- jr __PRINT_RESTART
-__PRINT_PAP:
- ld hl, __PRINT_PAP2
- jr __PRINT_SET_STATE
-__PRINT_PAP2:
- call PAPER_TMP
- jr __PRINT_RESTART
-__PRINT_FLA:
- ld hl, __PRINT_FLA2
- jr __PRINT_SET_STATE
-__PRINT_FLA2:
- call FLASH_TMP
- jr __PRINT_RESTART
-__PRINT_BRI:
- ld hl, __PRINT_BRI2
- jr __PRINT_SET_STATE
-__PRINT_BRI2:
- call BRIGHT_TMP
- jr __PRINT_RESTART
-__PRINT_INV:
- ld hl, __PRINT_INV2
- jr __PRINT_SET_STATE
-__PRINT_INV2:
- call INVERSE_TMP
- jr __PRINT_RESTART
-__PRINT_OVR:
- ld hl, __PRINT_OVR2
- jr __PRINT_SET_STATE
-__PRINT_OVR2:
- call OVER_TMP
- jr __PRINT_RESTART
-__PRINT_BOLD:
- ld hl, __PRINT_BOLD2
- jp __PRINT_SET_STATE
-__PRINT_BOLD2:
- call BOLD_TMP
- jp __PRINT_RESTART
-#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_ITA:
- ld hl, __PRINT_ITA2
- jp __PRINT_SET_STATE
-__PRINT_ITA2:
- call ITALIC_TMP
- jp __PRINT_RESTART
-#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __BOLD
-__BOLD:
- push hl
- ld hl, MEM0
- ld b, 8
-1:
- ld a, (de)
- ld c, a
- rlca
- or c
- ld (hl), a
- inc hl
- inc de
- djnz 1b
- pop hl
- ld de, MEM0
- ret
-#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __ITALIC
-__ITALIC:
- push hl
- ld hl, MEM0
- ex de, hl
- ld bc, 8
- ldir
- ld hl, MEM0
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- srl (hl)
- inc hl
- inc hl
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- inc hl
- sla (hl)
- pop hl
- ld de, MEM0
- ret
-#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __SCROLL_SCR
-#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL
-#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-PRINT_COMMA:
- call __LOAD_S_POSN
- ld a, e
- and 16
- add a, 16
-PRINT_TAB:
- ; Tabulates the number of spaces in A register
- ; If the current cursor position is already A, does nothing
- PROC
- LOCAL LOOP
- call __LOAD_S_POSN ; e = current row
- sub e
- and 31
- ret z
- ld b, a
-LOOP:
- ld a, ' '
- call __PRINTCHAR
- djnz LOOP
- ret
- ENDP
-PRINT_AT: ; Changes cursor to ROW, COL
- ; COL in A register
- ; ROW in stack
- pop hl ; Ret address
- ex (sp), hl ; callee H = ROW
- ld l, a
- ex de, hl
- call __IN_SCREEN
- ret nc ; Return if out of screen
- jp __SAVE_S_POSN
- LOCAL __PRINT_COM
- LOCAL __PRINT_AT1
- LOCAL __PRINT_AT2
- LOCAL __PRINT_BOLD
- LOCAL __PRINT_ITA
- LOCAL __PRINT_INK
- LOCAL __PRINT_PAP
- LOCAL __PRINT_SET_STATE
- LOCAL __PRINT_TABLE
- LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2
- LOCAL __PRINT_ITA2
-#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
- LOCAL __PRINT_BOLD2
-#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm"
-__PRINT_TABLE: ; Jump table for 0 .. 22 codes
- DW __PRINT_NOP ; 0
- DW __PRINT_NOP ; 1
- DW __PRINT_NOP ; 2
- DW __PRINT_NOP ; 3
- DW __PRINT_NOP ; 4
- DW __PRINT_NOP ; 5
- DW __PRINT_COM ; 6 COMMA
- DW __PRINT_NOP ; 7
- DW __PRINT_DEL ; 8 DEL
- DW __PRINT_NOP ; 9
- DW __PRINT_NOP ; 10
- DW __PRINT_NOP ; 11
- DW __PRINT_NOP ; 12
- DW __PRINT_0Dh ; 13
- DW __PRINT_BOLD ; 14
- DW __PRINT_ITA ; 15
- DW __PRINT_INK ; 16
- DW __PRINT_PAP ; 17
- DW __PRINT_FLA ; 18
- DW __PRINT_BRI ; 19
- DW __PRINT_INV ; 20
- DW __PRINT_OVR ; 21
- DW __PRINT_AT ; 22 AT
- DW __PRINT_TAB ; 23 TAB
- ENDP
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
- push namespace core
-COPY_ATTR:
- ; Just copies current permanent attribs into temporal attribs
- ; and sets print mode
- PROC
- LOCAL INVERSE1
- LOCAL __REFRESH_TMP
- INVERSE1 EQU 02Fh
- ld hl, (ATTR_P)
- ld (ATTR_T), hl
- ld hl, FLAGS2
- call __REFRESH_TMP
- ld hl, P_FLAG
- call __REFRESH_TMP
-__SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG)
- LOCAL TABLE
- LOCAL CONT2
- rra ; Over bit to carry
- ld a, (FLAGS2)
- rla ; Over bit in bit 1, Over2 bit in bit 2
- and 3 ; Only bit 0 and 1 (OVER flag)
- ld c, a
- ld b, 0
- ld hl, TABLE
- add hl, bc
- ld a, (hl)
- ld (PRINT_MODE), a
- ld hl, (P_FLAG)
- xor a ; NOP -> INVERSE0
- bit 2, l
- jr z, CONT2
- ld a, INVERSE1 ; CPL -> INVERSE1
-CONT2:
- ld (INVERSE_MODE), a
- ret
-TABLE:
- nop ; NORMAL MODE
- xor (hl) ; OVER 1 MODE
- and (hl) ; OVER 2 MODE
- or (hl) ; OVER 3 MODE
-#line 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm"
-__REFRESH_TMP:
- ld a, (hl)
- and 0b10101010
- ld c, a
- rra
- or c
- ld (hl), a
- ret
- ENDP
- pop namespace
-#line 120 "arch/zx48k/subrec.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm"
-; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
-; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
-; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | | |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | |
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
- ; ---------------------------------------------------------------------
- ; __MEM_INIT must be called to initalize this library with the
- ; standard parameters
- ; ---------------------------------------------------------------------
- push namespace core
-__MEM_INIT: ; Initializes the library using (RAMTOP) as start, and
- ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start
- ld de, ZXBASIC_HEAP_SIZE ; Change this with your size
- ; ---------------------------------------------------------------------
- ; __MEM_INIT2 initalizes this library
-; Parameters:
-; HL : Memory address of 1st byte of the memory heap
-; DE : Length in bytes of the Memory Heap
- ; ---------------------------------------------------------------------
-__MEM_INIT2:
- ; HL as TOP
- PROC
- dec de
- dec de
- dec de
- dec de ; DE = length - 4; HL = start
- ; This is done, because we require 4 bytes for the empty dummy-header block
- xor a
- ld (hl), a
- inc hl
- ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4
- inc hl
- ld b, h
- ld c, l
- inc bc
- inc bc ; BC = starts of next block
- ld (hl), c
- inc hl
- ld (hl), b
- inc hl ; Pointer to next block
- ld (hl), e
- inc hl
- ld (hl), d
- inc hl ; Block size (should be length - 4 at start); This block contains all the available memory
- ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block)
- inc hl
- ld (hl), a
- ld a, 201
- ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again
- ret
- ENDP
- pop namespace
-#line 69 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm"
- ; ---------------------------------------------------------------------
- ; MEM_FREE
- ; Frees a block of memory
- ;
-; Parameters:
- ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing
- ; is done
- ; ---------------------------------------------------------------------
- push namespace core
-MEM_FREE:
-__MEM_FREE: ; Frees the block pointed by HL
- ; HL DE BC & AF modified
- PROC
- LOCAL __MEM_LOOP2
- LOCAL __MEM_LINK_PREV
- LOCAL __MEM_JOIN_TEST
- LOCAL __MEM_BLOCK_JOIN
- ld a, h
- or l
- ret z ; Return if NULL pointer
- dec hl
- dec hl
- ld b, h
- ld c, l ; BC = Block pointer
- ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start
-__MEM_LOOP2:
- inc hl
- inc hl ; Next block ptr
- ld e, (hl)
- inc hl
- ld d, (hl) ; Block next ptr
- ex de, hl ; DE = &(block->next); HL = block->next
- ld a, h ; HL == NULL?
- or l
- jp z, __MEM_LINK_PREV; if so, link with previous
- or a ; Clear carry flag
- sbc hl, bc ; Carry if BC > HL => This block if before
- add hl, bc ; Restores HL, preserving Carry flag
- jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block
- ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next
-__MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL
- ex de, hl
- push hl
- dec hl
- ld (hl), c
- inc hl
- ld (hl), b ; (DE) <- BC
- ld h, b ; HL <- BC (Free block ptr)
- ld l, c
- inc hl ; Skip block length (2 bytes)
- inc hl
- ld (hl), e ; Block->next = DE
- inc hl
- ld (hl), d
- ; --- LINKED ; HL = &(BC->next) + 2
- call __MEM_JOIN_TEST
- pop hl
-__MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them
- ; hl = Ptr to current block + 2
- ld d, (hl)
- dec hl
- ld e, (hl)
- dec hl
- ld b, (hl) ; Loads block length into BC
- dec hl
- ld c, (hl) ;
- push hl ; Saves it for later
- add hl, bc ; Adds its length. If HL == DE now, it must be joined
- or a
- sbc hl, de ; If Z, then HL == DE => We must join
- pop hl
- ret nz
-__MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC
- push hl ; Saves it for later
- ex de, hl
- ld e, (hl) ; DE -> block->next->length
- inc hl
- ld d, (hl)
- inc hl
- ex de, hl ; DE = &(block->next)
- add hl, bc ; HL = Total Length
- ld b, h
- ld c, l ; BC = Total Length
- ex de, hl
- ld e, (hl)
- inc hl
- ld d, (hl) ; DE = block->next
- pop hl ; Recovers Pointer to block
- ld (hl), c
- inc hl
- ld (hl), b ; Length Saved
- inc hl
- ld (hl), e
- inc hl
- ld (hl), d ; Next saved
- ret
- ENDP
- pop namespace
-#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm"
- ; PRINT command routine
- ; Prints string pointed by HL
- push namespace core
-PRINT_STR:
-__PRINTSTR: ; __FASTCALL__ Entry to print_string
- PROC
- LOCAL __PRINT_STR_LOOP
- LOCAL __PRINT_STR_END
- ld d, a ; Saves A reg (Flag) for later
- ld a, h
- or l
- ret z ; Return if the pointer is NULL
- push hl
- ld c, (hl)
- inc hl
- ld b, (hl)
- inc hl ; BC = LEN(a$); HL = &a$
-__PRINT_STR_LOOP:
- ld a, b
- or c
- jr z, __PRINT_STR_END ; END if BC (counter = 0)
- ld a, (hl)
- call __PRINTCHAR
- inc hl
- dec bc
- jp __PRINT_STR_LOOP
-__PRINT_STR_END:
- pop hl
- ld a, d ; Recovers A flag
- or a ; If not 0 this is a temporary string. Free it
- ret z
- jp __MEM_FREE ; Frees str from heap and return from there
-__PRINT_STR:
- ; Fastcall Entry
- ; It ONLY prints strings
- ; HL = String start
- ; BC = String length (Number of chars)
- push hl ; Push str address for later
- ld d, a ; Saves a FLAG
- jp __PRINT_STR_LOOP
- ENDP
- pop namespace
-#line 122 "arch/zx48k/subrec.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu32.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi32.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm"
- push namespace core
-__PRINTU_START:
- PROC
- LOCAL __PRINTU_CONT
- ld a, b
- or a
- jp nz, __PRINTU_CONT
- ld a, '0'
- jp __PRINT_DIGIT
-__PRINTU_CONT:
- pop af
- push bc
- call __PRINT_DIGIT
- pop bc
- djnz __PRINTU_CONT
- ret
- ENDP
-__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers
- ld a, '-'
- jp __PRINT_DIGIT
- __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi32.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm"
- push namespace core
-__ABS32:
- bit 7, d
- ret z
-__NEG32: ; Negates DEHL (Two's complement)
- ld a, l
- cpl
- ld l, a
- ld a, h
- cpl
- ld h, a
- ld a, e
- cpl
- ld e, a
- ld a, d
- cpl
- ld d, a
- inc l
- ret nz
- inc h
- ret nz
- inc de
- ret
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi32.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div32.asm"
- ; ---------------------------------------------------------
- push namespace core
-__DIVU32: ; 32 bit unsigned division
- ; DEHL = Dividend, Stack Top = Divisor
- ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q
- ;
- ; Changes A, BC DE HL B'C' D'E' H'L'
- ; ---------------------------------------------------------
- exx
- pop hl ; return address
- pop de ; low part
- ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend
-__DIVU32START: ; Performs D'E'H'L' / HLDE
- ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B)
- push de ; push Lowpart(Q)
- ex de, hl ; DE = HL
- ld hl, 0
- exx
- ld b, h
- ld c, l
- pop hl
- push de
- ex de, hl
- ld hl, 0 ; H'L'HL = 0
- exx
- pop bc ; Pop HightPart(B) => B = B'C'BC
- exx
- ld a, 32 ; Loop count
-__DIV32LOOP:
- sll c ; B'C'BC << 1 ; Output most left bit to carry
- rl b
- exx
- rl c
- rl b
- exx
- adc hl, hl
- exx
- adc hl, hl
- exx
- sbc hl,de
- exx
- sbc hl,de
- exx
- jp nc, __DIV32NOADD ; use JP inside a loop for being faster
- add hl, de
- exx
- adc hl, de
- exx
- dec bc
-__DIV32NOADD:
- dec a
- jp nz, __DIV32LOOP ; use JP inside a loop for being faster
- ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL
- push hl
- exx
- pop de
- ex de, hl ; D'E'H'L' = 32 bits modulus
- push bc
- exx
- pop de ; DE = B'C'
- ld h, b
- ld l, c ; DEHL = quotient D'E'H'L' = Modulus
- ret ; DEHL = quotient, D'E'H'L' = Modulus
-__MODU32: ; 32 bit modulus for 32bit unsigned division
- ; DEHL = Dividend, Stack Top = Divisor (DE, HL)
- exx
- pop hl ; return address
- pop de ; low part
- ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend
- call __DIVU32START ; At return, modulus is at D'E'H'L'
-__MODU32START:
- exx
- push de
- push hl
- exx
- pop hl
- pop de
- ret
-__DIVI32: ; 32 bit signed division
- ; DEHL = Dividend, Stack Top = Divisor
- ; A = Dividend, B = Divisor => A / B
- exx
- pop hl ; return address
- pop de ; low part
- ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend
-__DIVI32START:
- exx
- ld a, d ; Save sign
- ex af, af'
- bit 7, d ; Negative?
- call nz, __NEG32 ; Negates DEHL
- exx ; Now works with H'L'D'E'
- ex af, af'
- xor h
- ex af, af' ; Stores sign of the result for later
- bit 7, h ; Negative?
- ex de, hl ; HLDE = DEHL
- call nz, __NEG32
- ex de, hl
- call __DIVU32START
- ex af, af' ; Recovers sign
- and 128 ; positive?
- ret z
- jp __NEG32 ; Negates DEHL and returns from there
-__MODI32: ; 32bits signed division modulus
- exx
- pop hl ; return address
- pop de ; low part
- ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend
- call __DIVI32START
- jp __MODU32START
- pop namespace
-#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/printi32.asm"
- push namespace core
-__PRINTI32:
- ld a, d
- or a
- jp p, __PRINTU32
- call __PRINT_MINUS
- call __NEG32
-__PRINTU32:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- ld a, h
- or l
- or d
- or e
- jp z, __PRINTU_START
- push bc
- ld bc, 0
- push bc
- ld bc, 10
- push bc ; Push 00 0A (10 Dec) into the stack = divisor
- call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- exx
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- exx
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu32.asm"
-#line 123 "arch/zx48k/subrec.bas"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
-#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div8.asm"
- ; --------------------------------
- push namespace core
-__DIVU8: ; 8 bit unsigned integer division
- ; Divides (Top of stack, High Byte) / A
- pop hl ; --------------------------------
- ex (sp), hl ; CALLEE
-__DIVU8_FAST: ; Does A / H
- ld l, h
- ld h, a ; At this point do H / L
- ld b, 8
- xor a ; A = 0, Carry Flag = 0
-__DIV8LOOP:
- sla h
- rla
- cp l
- jr c, __DIV8NOSUB
- sub l
- inc h
-__DIV8NOSUB:
- djnz __DIV8LOOP
- ld l, a ; save remainder
- ld a, h ;
- ret ; a = Quotient,
- ; --------------------------------
-__DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A
- pop hl ; --------------------------------
- ex (sp), hl
-__DIVI8_FAST:
- ld e, a ; store operands for later
- ld c, h
- or a ; negative?
- jp p, __DIV8A
- neg ; Make it positive
-__DIV8A:
- ex af, af'
- ld a, h
- or a
- jp p, __DIV8B
- neg
- ld h, a ; make it positive
-__DIV8B:
- ex af, af'
- call __DIVU8_FAST
- ld a, c
- xor l ; bit 7 of A = 1 if result is negative
- ld a, h ; Quotient
- ret p ; return if positive
- neg
- ret
-__MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODU8_FAST: ; __FASTCALL__ entry
- call __DIVU8_FAST
- ld a, l ; Remainder
- ret ; a = Modulus
-__MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands)
- pop hl
- ex (sp), hl ; CALLEE
-__MODI8_FAST: ; __FASTCALL__ entry
- call __DIVI8_FAST
- ld a, l ; remainder
- ret ; a = Modulus
- pop namespace
-#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm"
- push namespace core
-__PRINTI8: ; Prints an 8 bits number in Accumulator (A)
- ; Converts 8 to 32 bits
- or a
- jp p, __PRINTU8
- push af
- call __PRINT_MINUS
- pop af
- neg
-__PRINTU8:
- PROC
- LOCAL __PRINTU_LOOP
- ld b, 0 ; Counter
-__PRINTU_LOOP:
- or a
- jp z, __PRINTU_START
- push bc
- ld h, 10
- call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10)
- pop bc
- ld a, l
- or '0' ; Stores ASCII digit (must be print in reversed order)
- push af
- ld a, h
- inc b
- jp __PRINTU_LOOP ; Uses JP in loops
- ENDP
- pop namespace
-#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printu8.asm"
-#line 124 "arch/zx48k/subrec.bas"
+#line 96 "arch/zx48k/subrec.bas"
END
diff --git a/tests/functional/arch/zx48k/subrec.bas b/tests/functional/arch/zx48k/subrec.bas
index c568298e0..244558ae7 100644
--- a/tests/functional/arch/zx48k/subrec.bas
+++ b/tests/functional/arch/zx48k/subrec.bas
@@ -1,6 +1,7 @@
REM Factorial recursive test
DIM result as ulong = 1
+DIM dummy as ulong
sub fact(x as ulong)
if x < 2 then
@@ -15,5 +16,5 @@ cls
for x = 1 To 10:
result = 1
fact(x)
- print "Fact ("; x; ") = "; result
+ dummy = result
next x
diff --git a/tests/functional/arch/zx48k/read5.bas b/tests/runtime/cases/read_float_expr.bas
similarity index 52%
rename from tests/functional/arch/zx48k/read5.bas
rename to tests/runtime/cases/read_float_expr.bas
index 1bff2914d..8494ebfca 100644
--- a/tests/functional/arch/zx48k/read5.bas
+++ b/tests/runtime/cases/read_float_expr.bas
@@ -1,4 +1,4 @@
-REM Error x is an array, not an scalar
+#include "lib/tst_framework.bas"
DIM v as Float = 1.5
@@ -7,8 +7,14 @@ RESTORE
DATA 10, 25 * v, SIN(v) * tan(v)^2, PI * v
+INIT("Test READ float expressions")
+
+
DIM c, d as Float
+
FOR i = 1 TO 4:
-READ c, d
-PRINT c, d
+ READ c, d
+ PRINT c, d
NEXT i
+
+REPORT_OK
diff --git a/tests/functional/arch/zx48k/read10.bas b/tests/runtime/cases/read_float_func.bas
similarity index 66%
rename from tests/functional/arch/zx48k/read10.bas
rename to tests/runtime/cases/read_float_func.bas
index 1462adcc1..2108c3478 100644
--- a/tests/functional/arch/zx48k/read10.bas
+++ b/tests/runtime/cases/read_float_func.bas
@@ -1,4 +1,4 @@
-REM Error x is an array, not an scalar
+#include "lib/tst_framework.bas"
DIM v as Float = 1.5
@@ -6,6 +6,7 @@ RESTORE
DATA 10, 25 * v, SIN(v) * tan(v)^2, PI * v
+INIT("Test reading FP from\#013function body")
function p()
DIM c as Float
@@ -15,3 +16,5 @@ function p()
NEXT i
end function
p()
+
+REPORT_OK
diff --git a/tests/runtime/expected/read_float_expr.tzx.scr b/tests/runtime/expected/read_float_expr.tzx.scr
new file mode 100644
index 000000000..db2fbcb50
Binary files /dev/null and b/tests/runtime/expected/read_float_expr.tzx.scr differ
diff --git a/tests/runtime/expected/read_float_func.tzx.scr b/tests/runtime/expected/read_float_func.tzx.scr
new file mode 100644
index 000000000..5453267cf
Binary files /dev/null and b/tests/runtime/expected/read_float_func.tzx.scr differ