Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/api/python_version_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

def init():
if sys.version_info < MINIMUM_REQUIRED_PYTHON_VERSION:
sys.exit("Python 3.12 or later is required.")
sys.exit("Python %i.%i or later is required." % MINIMUM_REQUIRED_PYTHON_VERSION)


init()
10 changes: 0 additions & 10 deletions src/arch/z80/visitor/translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import src.api.global_ as gl
import src.api.tmp_labels
from src.api import check
from src.api.config import OPTIONS
from src.api.constants import CLASS, CONVENTION, SCOPE, TYPE
from src.api.debug import __DEBUG__
from src.api.errmsg import error
Expand Down Expand Up @@ -175,15 +174,6 @@ def visit_ARGLIST(self, node):
for i in range(len(node) - 1, -1, -1): # visit in reverse order
yield node[i]

if (
isinstance(node.parent, symbols.ARRAYACCESS)
and OPTIONS.array_check
and node.parent.entry.scope != SCOPE.parameter
):
upper = node.parent.entry.bounds[i].upper
lower = node.parent.entry.bounds[i].lower
self.ic_param(gl.PTR_TYPE, upper - lower)

def visit_ARGUMENT(self, node):
if not node.byref:
if node.value.token == "VAR" and node.type_.is_dynamic and node.value.t[0] == "$":
Expand Down
18 changes: 9 additions & 9 deletions src/arch/z80/visitor/var_translator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import src.api
from src.api import global_ as gl
from src.api.config import OPTIONS
from src.arch.z80 import Translator
from src.arch.z80.visitor.translator_visitor import TranslatorVisitor
from src.symbols import sym as symbols
Expand Down Expand Up @@ -43,16 +44,15 @@ def visit_ARRAYDECL(self, node):
if self.O_LEVEL > 1:
return

bound_ptrs = [] # Bound tables pointers (empty if not used)
lbound_label = entry.mangled + ".__LBOUND__"
ubound_label = entry.mangled + ".__UBOUND__"

if entry.lbound_used or entry.ubound_used:
bound_ptrs = ["0", "0"] # NULL by default
if entry.lbound_used:
bound_ptrs[0] = lbound_label
if entry.ubound_used:
bound_ptrs[1] = ubound_label
is_zero_based_array = all(bound.lower == 0 for bound in node.bounds)
bound_ptrs = ["0", "0"] # NULL by default
if entry.lbound_used or not is_zero_based_array:
bound_ptrs[0] = lbound_label
if entry.ubound_used or OPTIONS.array_check:
bound_ptrs[1] = ubound_label

data_label = entry.data_label
idx_table_label = src.api.tmp_labels.tmp_label()
Expand Down Expand Up @@ -87,10 +87,10 @@ def visit_ARRAYDECL(self, node):

self.ic_vard(idx_table_label, l)

if entry.lbound_used:
if bound_ptrs[0] != "0":
l = ["%04X" % bound.lower for bound in node.bounds]
self.ic_vard(lbound_label, l)

if entry.ubound_used:
if bound_ptrs[1] != "0":
l = ["%04X" % bound.upper for bound in node.bounds]
self.ic_vard(ubound_label, l)
95 changes: 67 additions & 28 deletions src/lib/arch/zx48k/runtime/array.asm
Original file line number Diff line number Diff line change
Expand Up @@ -28,67 +28,110 @@ __ARRAY_PTR: ;; computes an array offset from a pointer
ld c, (hl)
inc hl
ld h, (hl)
ld l, c
ld l, c ;; HL <-- [HL]

__ARRAY:
PROC

LOCAL LOOP
LOCAL ARRAY_END
LOCAL RET_ADDRESS ; Stores return address
LOCAL TMP_ARR_PTR ; Stores pointer temporarily
LOCAL TMP_ARR_PTR ; Ptr to Array DATA region. Stored temporarily
LOCAL LBOUND_PTR, UBOUND_PTR ; LBound and UBound PTR indexes
LOCAL RET_ADDR ; Contains the return address popped from the stack

LBOUND_PTR EQU 23698 ; Uses MEMBOT as a temporary variable
UBOUND_PTR EQU LBOUND_PTR + 2 ; Next 2 bytes for UBOUND PTR
RET_ADDR EQU UBOUND_PTR + 2 ; Next 2 bytes for RET_ADDR
TMP_ARR_PTR EQU RET_ADDR + 2 ; Next 2 bytes for TMP_ARR_PTR

ld e, (hl)
inc hl
ld d, (hl)
inc hl ; DE <-- PTR to Dim sizes table
ld (TMP_ARR_PTR), hl ; HL = Array __DATA__.__PTR__
inc hl
ld (TMP_ARR_PTR), hl
ex de, hl
ex (sp), hl ; Return address in HL, array address in the stack
ld (RET_ADDRESS + 1), hl ; Stores it for later
inc hl
ld c, (hl)
inc hl
ld b, (hl) ; BC <-- Array __LBOUND__ PTR
ld (LBOUND_PTR), bc ; Store it for later

#ifdef __CHECK_ARRAY_BOUNDARY__
inc hl
ld c, (hl)
inc hl
ld b, (hl) ; BC <-- Array __UBOUND__ PTR
ld (UBOUND_PTR), bc
#endif

ex de, hl ; HL <-- PTR to Dim sizes table, DE <-- dummy
ex (sp), hl ; Return address in HL, PTR Dim sizes table onto Stack
ld (RET_ADDR), hl ; Stores it for later

exx
pop hl ; Will use H'L' as the pointer
pop hl ; Will use H'L' as the pointer to Dim sizes table
ld c, (hl) ; Loads Number of dimensions from (hl)
inc hl
ld b, (hl)
inc hl ; Ready
exx

ld hl, 0 ; HL = Offset "accumulator"
ld hl, 0 ; HL = Element Offset "accumulator"

LOOP:
#ifdef __CHECK_ARRAY_BOUNDARY__
pop de
#endif
pop bc ; Get next index (Ai) from the stack
ex de, hl ; DE = Element Offset
ld hl, (LBOUND_PTR)
ld a, h
or l
ld b, h
ld c, l
jr z, 1f
ld c, (hl)
inc hl
ld b, (hl)
inc hl
ld (LBOUND_PTR), hl
1:
pop hl ; Get next index (Ai) from the stack
sbc hl, bc ; Subtract LBOUND

#ifdef __CHECK_ARRAY_BOUNDARY__
ex de, hl
or a
sbc hl, bc
ld a, ERROR_SubscriptWrong
jp c, __ERROR
ex de, hl
push hl ; Saves (Ai) - Lbound(i)
add hl, bc ; Recover original (Ai) value
push hl
ld hl, (UBOUND_PTR)
ld c, (hl)
inc hl
ld b, (hl)
inc hl
ld (UBOUND_PTR), hl
pop hl ; original (Ai) value
scf
sbc hl, bc ; HL <- HL - BC - 1 = Ai - UBound(i) - 1 => No Carry if Ai > UBound(i)
jp nc, __ERROR
pop hl ; Recovers (Ai) - Lbound(Ai)
#endif

add hl, bc ; Adds current index
add hl, de ; Adds current index

exx ; Checks if B'C' = 0
ld a, b ; Which means we must exit (last element is not multiplied by anything)
or c
jr z, ARRAY_END ; if B'Ci == 0 we are done
dec bc ; Decrements loop counter

ld e, (hl) ; Loads next dimension into D'E'
ld e, (hl) ; Loads next dimension size into D'E'
inc hl
ld d, (hl)
inc hl
push de
dec bc ; Decrements loop counter
exx

pop de ; DE = Max bound Number (i-th dimension)

call __FNMUL
call __FNMUL ; HL <= HL * DE mod 65536
jp LOOP

ARRAY_END:
Expand Down Expand Up @@ -118,9 +161,9 @@ ARRAY_SIZE_LOOP:
ld h, (hl)
ld l, a
add hl, de ; Adds element start

RET_ADDRESS:
jp 0
ld de, (RET_ADDR)
push de
ret

;; Performs a faster multiply for little 16bit numbs
LOCAL __FNMUL, __FNMUL2
Expand All @@ -143,10 +186,6 @@ __FNMUL2:
djnz __FNMUL2
ret

TMP_ARR_PTR:
DW 0 ; temporary storage for pointer to tables

ENDP

pop namespace

Loading