memset fixed

This commit is contained in:
Irmen de Jong 2018-01-13 22:42:07 +01:00
parent 1990f75e98
commit faa08133a8
7 changed files with 110 additions and 38 deletions

View File

@ -86,7 +86,8 @@ class PlyParser:
zeropage = Zeropage(module.zp_options)
for vardef in zpnode.scope.filter_nodes(VarDef):
try:
vardef.zp_address = zeropage.allocate(vardef)
if vardef.vartype == VarType.VAR:
vardef.zp_address = zeropage.allocate(vardef)
except CompileError as x:
raise ParseError(str(x), vardef.sourceref)

View File

@ -338,9 +338,14 @@ class AssemblyGenerator:
assert len(vardef.size) == 1
self.p("\v{:s} = {:s}\t; array of {:d} words".format(vardef.name, to_hex(vardef.value), vardef.size[0]))
elif vardef.datatype == DataType.MATRIX:
assert len(vardef.size) == 2
self.p("\v{:s} = {:s}\t; matrix of {:d} by {:d} = {:d} bytes"
.format(vardef.name, to_hex(vardef.value), vardef.size[0], vardef.size[1], vardef.size[0]*vardef.size[1]))
assert len(vardef.size) in (2, 3)
if len(vardef.size) == 2:
comment = "matrix of {:d} by {:d} = {:d} bytes".format(vardef.size[0], vardef.size[1], vardef.size[0]*vardef.size[1])
elif len(vardef.size) == 3:
comment = "matrix of {:d} by {:d}, interleave {:d}".format(vardef.size[0], vardef.size[1], vardef.size[2])
else:
raise CodeError("matrix size should be 2 or 3 numbers")
self.p("\v{:s} = {:s}\t; {:s}".format(vardef.name, to_hex(vardef.value), comment))
else:
raise CodeError("invalid var type")
self.p("; normal variables - initial values will be set by init code")

View File

@ -20,6 +20,7 @@
memory .byte SFDX = $cb ; current key pressed (matrix value) (updated by IRQ)
memory .byte COLOR = $0286 ; cursor color
memory .byte HIBASE = $0288 ; screen base address / 256 (hi-byte of screen memory address)
memory .word CINV = $0314 ; IRQ vector
memory .matrix(40, 25) Screen = $0400 ; default character screen matrix
memory .matrix(40, 25) Colors = $d800 ; character screen colors
@ -452,6 +453,7 @@ sub float_sub_SW1_from_XY (mflt: XY) -> (?) {
sub clear_screen (char:A, color: Y) -> () {
; ---- clear the character screen with the given fill character and character color.
; (assumes screen is at $0400, could be altered in the future with self-modifying code)
; @todo X = SCREEN ADDR HI BYTE
%asm {
sta _loop + 1 ; self-modifying
@ -486,7 +488,7 @@ sub scroll_left_full (alsocolors: SC) -> (A?, X?, Y?) {
bcs +
jmp _scroll_screen
+
+ ; scroll the color memory
ldx #0
ldy #38
-
@ -509,7 +511,7 @@ sub scroll_left_full (alsocolors: SC) -> (A?, X?, Y?) {
dey
bpl -
_scroll_screen
_scroll_screen ; scroll the screen memory
ldx #0
ldy #38
-
@ -545,7 +547,7 @@ sub scroll_right_full (alsocolors: SC) -> (A?, X?) {
bcs +
jmp _scroll_screen
+
+ ; scroll the color memory
ldx #38
-
.for row=0, row<=12, row+=1
@ -564,7 +566,7 @@ sub scroll_right_full (alsocolors: SC) -> (A?, X?) {
dex
bpl -
_scroll_screen
_scroll_screen ; scroll the screen memory
ldx #38
-
.for row=0, row<=12, row+=1
@ -596,7 +598,7 @@ sub scroll_up_full (alsocolors: SC) -> (A?, X?) {
bcs +
jmp _scroll_screen
+
+ ; scroll the color memory
ldx #39
-
.for row=1, row<=11, row+=1
@ -615,7 +617,7 @@ sub scroll_up_full (alsocolors: SC) -> (A?, X?) {
dex
bpl -
_scroll_screen
_scroll_screen ; scroll the screen memory
ldx #39
-
.for row=1, row<=11, row+=1
@ -647,7 +649,7 @@ sub scroll_down_full (alsocolors: SC) -> (A?, X?) {
bcs +
jmp _scroll_screen
+
+ ; scroll the color memory
ldx #39
-
.for row=23, row>=12, row-=1
@ -666,7 +668,7 @@ sub scroll_down_full (alsocolors: SC) -> (A?, X?) {
dex
bpl -
_scroll_screen
_scroll_screen ; scroll the screen memory
ldx #39
-
.for row=23, row>=12, row-=1

View File

@ -88,29 +88,84 @@ memcopy
rts
; fill memory from (SCRATCH_ZPWORD1) length X (1-256, 0=256) with value in A.
; fill memory from (SCRATCH_ZPWORD1), length XY, with value in A.
; clobbers X, Y
memset ldy #0
- sta (SCRATCH_ZPWORD1), y
iny
dex
bne -
rts
; fill memory from (SCRATCH_ZPWORD1) length X (1-256, 0=256) with word value in AY.
; clobbers A, X, Y
memsetw sty _mod_hi+1 ; self-modify
sta _mod_lo+1 ; self-modify
memset stx SCRATCH_ZP1
sty SCRATCH_ZP2
ldy #0
_mod_lo lda #$00 ; self-modified
sta (SCRATCH_ZPWORD1), y
iny
_mod_hi lda #$00 ; self-modified
sta (SCRATCH_ZPWORD1), y
ldx SCRATCH_ZP2
beq _lastpage
_fullpage sta (SCRATCH_ZPWORD1),y
iny
bne _fullpage
inc SCRATCH_ZPWORD1+1 ; next page
dex
bne _mod_lo
rts
bne _fullpage
_lastpage ldy SCRATCH_ZP1
beq +
- dey
sta (SCRATCH_ZPWORD1),y
bne -
+ rts
; fill memory from (SCRATCH_ZPWORD1) number of words in SCRATCH_ZPWORD2, with word value in AY.
; clobbers A, X, Y
memsetw
sta _mod1+1 ; self-modify
sty _mod1b+1 ; self-modify
sta _mod2+1 ; self-modify
sty _mod2b+1 ; self-modify
ldx SCRATCH_ZPWORD1
stx SCRATCH_ZP1
ldx SCRATCH_ZPWORD1+1
inx
stx SCRATCH_ZP2 ; second page
ldy #0
ldx SCRATCH_ZPWORD2+1
beq _lastpage
_fullpage
_mod1 lda #0 ; self-modified
sta (SCRATCH_ZPWORD1),y ; first page
sta (SCRATCH_ZP1),y ; second page
iny
_mod1b lda #0 ; self-modified
sta (SCRATCH_ZPWORD1),y ; first page
sta (SCRATCH_ZP1),y ; second page
iny
bne _fullpage
inc SCRATCH_ZPWORD1+1 ; next page pair
inc SCRATCH_ZPWORD1+1 ; next page pair
inc SCRATCH_ZP1+1 ; next page pair
inc SCRATCH_ZP1+1 ; next page pair
dex
bne _fullpage
_lastpage ldx SCRATCH_ZPWORD2
beq _done
ldy #0
-
_mod2 lda #0 ; self-modified
sta (SCRATCH_ZPWORD1), y
inc SCRATCH_ZPWORD1
bne _mod2b
inc SCRATCH_ZPWORD1+1
_mod2b lda #0 ; self-modified
sta (SCRATCH_ZPWORD1), y
inc SCRATCH_ZPWORD1
bne +
inc SCRATCH_ZPWORD1+1
+ dex
bne -
_done rts
}
}

View File

@ -56,7 +56,8 @@ def main() -> None:
print()
if args.startvice:
print("Autostart vice emulator...")
cmdline = ["x64", "-remotemonitor", "-moncommands", mon_command_file,
# "-remotemonitor"
cmdline = ["x64", "-moncommands", mon_command_file,
"-autostartprgmode", "1", "-autostart-warp", "-autostart", program_filename]
with open(os.devnull, "wb") as shutup:
subprocess.call(cmdline, stdout=shutup)

View File

@ -203,12 +203,13 @@ def dimensions_validator(obj: 'DatatypeNode', attrib: attr.Attribute, value: Lis
else:
raise ParseError("array must have only one dimension", obj.sourceref)
if dt == DataType.MATRIX:
if len(value) == 2:
size = value[0] * value[1]
if size <= 0 or size > 0x8000:
raise ParseError("matrix size columns * rows must be 1..32768", obj.sourceref)
else:
raise ParseError("matrix must have two dimensions", obj.sourceref)
if len(value) < 2 or len(value) > 3:
raise ParseError("matrix must have two dimensions, with optional interleave", obj.sourceref)
if len(value) == 3:
if value[2] < 1 or value[2] > 256:
raise ParseError("matrix interleave must be 1..256", obj.sourceref)
if value[0] < 0 or value[0] > 128 or value[1] < 0 or value[1] > 128:
raise ParseError("matrix rows and columns must be 1..128", obj.sourceref)
@attr.s(cmp=False, repr=False)
@ -440,6 +441,10 @@ class VarDef(AstNode):
self.value.processed_expr_must_be_constant = True
elif self.value is None and self.datatype in (DataType.BYTE, DataType.WORD, DataType.FLOAT):
self.value = 0
# if it's a matrix with interleave, it must be memory mapped
if self.datatype == DataType.MATRIX and len(self.size) == 3:
if self.vartype != VarType.MEMORY:
raise ParseError("matrix with interleave can only be a memory-mapped variable", self.sourceref)
# note: value coercion is done later, when all expressions are evaluated
def process_expressions(self, scope: Scope) -> None:

View File

@ -594,6 +594,9 @@ Allows us to create pre calculated sine tables and such. Something like:
- strings: identical operations as on lists.
- matrix with row-interleave can only be a memory mapped variable and can be used to directly
access a rectangular area within another piece of memory - such as a rectangle on the (character) screen
these should call (or emit inline) optimized pieces of assembly code, so they run as fast as possible