Log on 23.1.2010

It seems Effectus has problems dealing with negation assignments, for example: A=-A. I found this issue compiling test program from viktorcech, who put his example on Effectus forum. I investigated the problem a little, but found out I will have to look at it a little deeper.

Log on 21.1.2010 - Effectus v0.0.15

I fixed the problem of FOR loops not allowing iterations higher than 255 with a method for handling 16-bit numbers. Now Effectus determines the type of loop iteration variable and generates appropriate code:

      8-bit code example:
      
      mva #1 I
      for_loop1
      jsr printf
      dta c'%',$9b,0
      dta a(i)
      inc I
      ldx I
      cpx #6
      jcc for_loop1

      16-bit code example:      

      mwa #1 N
      mwa #25601 STORE3
      for_loop4
      inw N
      lda N
      cmp STORE3
      lda N+1
      sbc STORE3+1
      jcc for_loop4

The maximum iteration value is placed in temporary variable named STORE3, which is used in FOR loop manipulation. STORE3 label resides in page zero memory location $CD in equates.asm file in lib directory.

- Functions (FUNC statement)

Currently only one parameter variable is allowed as resulting value in RETURN statement.

For example:

CARD FUNC Sum(BYTE nn1, nn2)
CARD result

result=nn1+nn2

RETURN(result)

- 8-bit math addition works only on values to 510 and you must use CARD type for resulting value

- 16-bit math addition:
   - Only CARD and INT value types are allowed, but also literal byte values (0 to 255) are allowed

- 16-bit math subtraction:
   - Only CARD and INT value types are allowed, but also literal byte values (0 to 255) are allowed

Found bugs

- Sometimes unexpected error arises, determining something is missing in Effectus code even this is not the case. To get around this, please insert a line with comments (;) before detected unworking code. I will investigate the issue.

- Using variables of type BYTE (CHAR) results in improper functioning of arithmetic operators MOD, ==+, ==-, ==*, and ==/. The way around this is using CARD and INT variable types, which work properly.

- Parameters of different types not allowed in PROCedure's and FUNCtion's parameter list.

To do

- Math type casts for determining largest value type to eliminate the problem of calculations with operands of different types.
- Independent local variables, which would not conflict with global variables and other PROCs and FUNCs local variables.


Log on 25.6.2010

Declaring machine language code in PROCs and FUNCs

I observed the way Action! handles machine code directly in the source code. Using [] pair you can include machine code to your existing code making even more flexible and faster code. The method can be used in PROC / FUNC statements, in the middle of your code, or as ARRAY declaration code. Also, parameters can be passed. For now, I implemented handling machine code in PROC / FUNC code with only one BYTE variable possible as a parameter. The code in [] can be coded in multiple lines and ML mnemonics can be written in hexadecimal or decimal format. The whole thing is in experimental stage for now, but it will be eventually more complete.

Current state of the functionality:

- Hex numbers and decimal numbers allowed (hex format is required when no spaces are used)
- Can be individual byte or address (e.g. $2C6), parsed as low/high pair of address
- Only necessary bytes of RAM consumed

To do:
- Any number of parameters
- Direct procedure calls from [] code
- Using [] feature from elsewhere in the program

Some Examples:

PROC PokeTest=*()[$A9 $30 $8D 710 $0 $60]

proc PokeTest2=*()[$A9$60$8D$02C6$0$60]

proc PokeTest3=*()[
				   $A9 $90
                   $8D $02C6
                   $0 $60
				  ]

PROC Param=*(BYTE a)[$8D$02C6$0$60]


Better SCopy, SCopyS and SAssign string handling

I shortened the method of filling literal characters in array string variables by using a loop (the same method used as copying one array string to another. In SCopy procedure, y registed is removed as an array index, because x register is sufficient for indexing and incrementing the counter.

;SCopy(str1, "Atari")

New code:

; Assignig literal string
 ldx #0
for_loop_22
 mva _SCOPY_buffer_22,x str1,x
 inx
 cpx #5
 jcc for_loop_22
 jsr printf
 dta '#',$9b,0
 dta a(str1)

; Declaring the string
_SCOPY_buffer_22 .byte 'Atari', $9b
 
Old code:

 ldy #0
 mva #'A' str1,y
 iny
 mva #'t' str1,y
 iny
 mva #'a' str1,y
 iny
 mva #'r' str1,y
 iny
 mva #'i' str1,y
 iny
 mva #$9b str1,y

Global strx string variable is now removed from common.asm (core library) file:

.array strx 255 .byte = $ff
.enda
 .var array_buffer_strx .word
 .var array_index_strx .byte

I also redesigned code for these commands to make them more flexible. Parameters can be literal values or variables.


New ARRAY functionality

I decided to look in more detail the way Action! language handles arrays. The reason for this is that language can handle both numbers and strings as elements of the array. Obviously, it uses a pointer to the address of declared INT or CARD ARRAY variable and from that point it knows how to handle all assigned values. BYTE or CHAR arrays are simply sets of continuous bytes. Back to INT / CARD arrays, it is allowed to set a cardinal value or string to specific array element:

CARD ARRAY item(1)

item(0)=2005
item(1)="This is a string"
It forced me to think about implementing this feature to my existing Effectus code. Yeah, it was hard at the beginning, because I had to review all existing code. When I finally grasp the logic of the code, I looked at handling the arrays. Now every CARD or INT array element gets also its BYTE array representation to hold string values. Sure, it is far from ideal way of doing this. It consumes 40 bytes for every string value, even if is not used, but at least it works. Of course, all that can be removed from generated asm code and you can compile optimized code with MADS assembler again. I will think about this problem in next version and try to avoid unused variables. Additional assembler code for such arrays is shown in the following excerpt code:
; Declaration
 .var i .word
.array item 2 .word = $ff
.enda
.array item_array_str_0 40 .byte = $ff
.enda
.array item_array_str_1 40 .byte = $ff
.enda
.array item_array_str_2 40 .byte = $ff
.enda
 .var array_buffer_item .word
 .var array_index_item .byte

; Body
 mwa #23456 item[0]

 ldx #0
for_loop_24
 mva _str_buffer_24,x item_array_str_1,x
 inx
 cpx #5
 jcc for_loop_24

 ldx #0
for_loop_25
 mva _str_buffer_25,x item_array_str_2,x
 inx
 cpx #5
 jcc for_loop_25

; Show results
 mwa item[0] i
 jsr printf
 dta c'%',$9b,0
 dta a(i)
 jsr printf
 dta '#',$9b,0
 dta a(item_array_str_1)
 jsr printf
 dta '#',$9b,0
 dta a(item_array_str_2)

; Init code
_str_buffer_24 .byte 'Atari',$9b
_str_buffer_25 .byte 'Another string',$9b  

Bug report

Some errors appeared in new version of Effectus (0.0.14):

- Strange behaviour of PutE in some places of the code
- FUNC returns no result
- Declaring variables in initialization stage doesn't work (for example BYTE n=[4]). It must be something with new functionality of declaring machine code in PROCs and FUNCs
- Compile error when comment includes ELSE directive (I will have to check for other directives and statements)


To do

- Local variables 
- More complete functionality of arrays of TYPE records (string support)
- DEFINE constants (partly implemented, currently only literal numeric values allowed)
- Recursion (non-Action! functionality)
- Nested procedures and functions (non-Action! functionality)
- Support for player/missiles
- Floating point support
- UNTIL loop support
- Syntax checking
- Multi-line statements
- WHILE loop (changing beginning offset to anything else than 0)
- implementing MADS features and compiling options
- remaining set of procedures, functions and other functionality of Action! language
- ...