1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-20 20:31:56 +00:00

Readded nop cast inlining - and fixed some recursion problems.

This commit is contained in:
jespergravgaard 2019-05-30 21:38:12 +02:00
parent 33b75c3db6
commit 036724c92d
34 changed files with 488 additions and 609 deletions

View File

@ -236,7 +236,6 @@ public class Compiler {
optimizations.add(new PassNAddNumberTypeConversions(program));
optimizations.add(new PassNAddArrayNumberTypeConversions(program));
optimizations.add(new Pass2InlineCast(program));
//optimizations.add(new Pass2NopCastInlining(program));
optimizations.add(new PassNCastSimplification(program));
optimizations.add(new PassNFinalizeNumberTypeConversions(program));
optimizations.add(new PassNTypeInference(program));
@ -307,6 +306,7 @@ public class Compiler {
List<Pass2SsaOptimization> constantOptimizations = new ArrayList<>();
constantOptimizations.add(new PassNStatementIndices(program));
constantOptimizations.add(new PassNVariableReferenceInfos(program));
constantOptimizations.add(new Pass2NopCastInlining(program));
constantOptimizations.add(new Pass2MultiplyToShiftRewriting(program));
constantOptimizations.add(new Pass2ConstantInlining(program));
constantOptimizations.add(new Pass2ConstantAdditionElimination(program));

View File

@ -4,6 +4,7 @@ import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
@ -12,8 +13,7 @@ import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.SymbolRef;
import dk.camelot64.kickc.model.values.VariableRef;
import java.util.LinkedHashMap;
import java.util.ListIterator;
import java.util.*;
/**
* Compiler Pass inlineng cast assignments that has no effect (byte to/from signed byte, word to/from signed word)
@ -24,12 +24,19 @@ public class Pass2NopCastInlining extends Pass2SsaOptimization {
super(program);
}
/** We can either inline intermediate vars or expressions - not both at once */
enum Mode { VARS, EXPR }
/**
* Inline cast assignments that has no effect (byte to/from signed byte, word to/from signed word)
*/
@Override
public boolean step() {
LinkedHashMap<SymbolRef, RValue> castAliasses = new LinkedHashMap<>();
LinkedHashMap<SymbolRef, RValue> replace1 = new LinkedHashMap<>();
LinkedHashMap<SymbolRef, RValue> replace2 = new LinkedHashMap<>();
Set<SymbolRef> delete = new HashSet<>();
Mode mode = null;
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
@ -58,20 +65,59 @@ public class Pass2NopCastInlining extends Pass2SsaOptimization {
isNopCast = true;
}
if(isNopCast && assignment.getlValue() instanceof VariableRef) {
getLog().append("Inlining Noop Cast " + assignment.toString(getProgram(), false));
// Add the alias for replacement
castAliasses.put((VariableRef) assignment.getlValue(), assignment.getrValue2());
// Remove the assignment
stmtIt.remove();
}
boolean handled = false;
if(castValue.getValue() instanceof VariableRef && ((VariableRef)castValue.getValue()).isIntermediate()) {
if(mode==null || mode==Mode.VARS ) {
mode = Mode.VARS;
Collection<Integer> varUseStatements = getProgram().getVariableReferenceInfos().getVarUseStatements((VariableRef) castValue.getValue());
if(varUseStatements.size() == 1 && assignment.getIndex().equals(varUseStatements.iterator().next())) {
// Cast variable is only ever used in the cast
getLog().append("Inlining Noop Cast " + assignment.toString(getProgram(), false) + " keeping " + assignment.getlValue());
// 1. Inline the cast
replace1.put((VariableRef) assignment.getlValue(), castValue);
// 2. Rename the cast variable (since we like the assignment variable better)
replace2.put((SymbolRef) castValue.getValue(), assignment.getlValue());
// 3. Delete the cast variable
delete.add((SymbolRef) castValue.getValue());
// Change the type of the assignment variable
Variable assignmentVar = getScope().getVariable((VariableRef) assignment.getlValue());
Variable castVar = getScope().getVariable((VariableRef) castValue.getValue());
assignmentVar.setType(castVar.getType());
// Remove the assignment
stmtIt.remove();
handled = true;
}
}
}
if(!handled) {
if(mode==null || mode==Mode.EXPR) {
mode = Mode.EXPR;
getLog().append("Inlining Noop Cast " + assignment.toString(getProgram(), false) + " keeping " + castValue.getValue());
// 1. Inline the cast
replace1.put((VariableRef) assignment.getlValue(), assignment.getrValue2());
// 2. Delete the assignment variable
delete.add((VariableRef) assignment.getlValue());
// Remove the assignment
stmtIt.remove();
}
}
}
}
}
}
}
replaceVariables(castAliasses);
deleteSymbols(getScope(), castAliasses.keySet());
return (castAliasses.size() > 0);
if(replace1.size()>0) {
// 1. Perform first replace
replaceVariables(replace1);
// 2. Perform second replace
replaceVariables(replace2);
// 3. Delete unused symbols
deleteSymbols(getScope(), delete);
}
return (replace1.size() > 0);
}

View File

@ -1,13 +1,12 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.ConstantNotLiteral;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary;
import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
import dk.camelot64.kickc.model.operators.Operator;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.PointerDereferenceSimple;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.*;
import java.util.concurrent.atomic.AtomicBoolean;
@ -31,19 +30,19 @@ public class PassNSimplifyExpressionWithZero extends Pass2SsaOptimization {
RValue right = binary.getRight();
Operator operator = programExpression.getOperator();
if(Operators.PLUS.equals(operator) || Operators.MINUS.equals(operator) || Operators.BOOL_OR.equals(operator) || Operators.BOOL_XOR.equals(operator)) {
if(left instanceof ConstantInteger && ((ConstantInteger) left).getInteger() == 0) {
getLog().append("Simplifying expression containing zero " + binary.getRight().toString()+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false)));
if(isZero(left)) {
getLog().append("Simplifying expression containing zero " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false)));
if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed) {
programExpression.set(new PointerDereferenceSimple(binary.getRight()));
} else {
} else {
programExpression.set(binary.getRight());
}
modified.set(true);
} else if(right instanceof ConstantInteger && ((ConstantInteger) right).getInteger() == 0) {
getLog().append("Simplifying expression containing zero " + binary.getLeft().toString()+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false)));
} else if(isZero(right)) {
getLog().append("Simplifying expression containing zero " + binary.getLeft().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false)));
if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed) {
programExpression.set(new PointerDereferenceSimple(binary.getLeft()));
} else {
} else {
programExpression.set(binary.getLeft());
}
modified.set(true);
@ -55,4 +54,25 @@ public class PassNSimplifyExpressionWithZero extends Pass2SsaOptimization {
return modified.get();
}
/**
* Determine if an RValue is effectively a zero
*
* @param left
* @return
*/
public boolean isZero(RValue left) {
if(left instanceof ConstantInteger && ((ConstantInteger) left).getInteger() == 0) {
return true;
} else if(left instanceof ConstantValue) {
try {
ConstantLiteral literal = ((ConstantValue) left).calculateLiteral(getProgram().getScope());
if(literal instanceof ConstantInteger && ((ConstantInteger) literal).getInteger() == 0L)
return true;
} catch(ConstantNotLiteral e) {
// Ignore
}
}
return false;
}
}

View File

@ -8,15 +8,13 @@ main: {
.const y0 = 0
.const x1 = $27
.const y1 = $18
.const xd = x1-x0
.const yd = y1-y0
.label x = 4
.label idx = 2
.label y = 5
.label _16 = 6
lda #y0
sta y
ldx #yd/2
ldx #y1/2
lda #x0
sta x
lda #0
@ -39,8 +37,8 @@ main: {
inc idx+1
!:
txa
axs #-[yd]
cpx #xd
axs #-[y1]
cpx #x1
bcc b2
beq b2
inc y
@ -52,7 +50,7 @@ main: {
inc idx+1
!:
txa
axs #xd
axs #x1
b2:
lda x
cmp #x1+1

View File

@ -166,12 +166,10 @@ gfx_mode: {
.label _36 = 9
.label _40 = 3
.label _42 = 3
.label _52 = 3
.label _53 = 3
.label _54 = 3
.label _55 = 3
.label _56 = 2
.label _57 = 3
.label _58 = 3
.label _59 = 3
.label plane_a = 9
@ -1150,13 +1148,12 @@ form_render_values: {
form_field_ptr: {
.label line = 3
.label x = $13
.label _2 = 3
lda form_fields_y,x
tay
lda form_line_hi,y
sta _2+1
sta line+1
lda form_line_lo,y
sta _2
sta line
lda form_fields_x,x
sta x
rts
@ -1534,7 +1531,6 @@ gfx_init_plane_fill: {
.label _1 = 3
.label _4 = 3
.label _5 = 3
.label _6 = 3
.label gfxb = 3
.label by = 7
.label plane_addr = 9
@ -1572,12 +1568,12 @@ gfx_init_plane_fill: {
and #>$3fff
sta _5+1
clc
lda _6
lda gfxb
adc #<$4000
sta _6
lda _6+1
sta gfxb
lda gfxb+1
adc #>$4000
sta _6+1
sta gfxb+1
lda #0
sta by
b1:
@ -2072,7 +2068,6 @@ bitmap_line_xdyi: {
}
// bitmap_plot(byte register(X) x, byte register(Y) y)
bitmap_plot: {
.label _0 = 3
.label plotter_x = 3
.label plotter_y = 5
.label plotter = 3
@ -2084,13 +2079,13 @@ bitmap_plot: {
sta plotter_y+1
lda bitmap_plot_ylo,y
sta plotter_y
lda _0
lda plotter
clc
adc plotter_y
sta _0
lda _0+1
sta plotter
lda plotter+1
adc plotter_y+1
sta _0+1
sta plotter+1
lda bitmap_plot_bit,x
ldy #0
ora (plotter),y
@ -2204,11 +2199,10 @@ bitmap_line_ydxd: {
bitmap_clear: {
.label bitmap = 3
.label y = 2
.label _3 = 3
lda bitmap_plot_xlo
sta _3
sta bitmap
lda bitmap_plot_xhi
sta _3+1
sta bitmap+1
lda #0
sta y
b1:

View File

@ -1685,7 +1685,6 @@ bitmap_line_xdyi: {
}
// bitmap_plot(byte register(X) x, byte register(Y) y)
bitmap_plot: {
.label _0 = 2
.label plotter_x = 2
.label plotter_y = 5
.label plotter = 2
@ -1697,13 +1696,13 @@ bitmap_plot: {
sta plotter_y+1
lda bitmap_plot_ylo,y
sta plotter_y
lda _0
lda plotter
clc
adc plotter_y
sta _0
lda _0+1
sta plotter
lda plotter+1
adc plotter_y+1
sta _0+1
sta plotter+1
lda bitmap_plot_bit,x
ldy #0
ora (plotter),y
@ -1817,11 +1816,10 @@ bitmap_line_ydxd: {
bitmap_clear: {
.label bitmap = 2
.label y = 4
.label _3 = 2
lda bitmap_plot_xlo
sta _3
sta bitmap
lda bitmap_plot_xhi
sta _3+1
sta bitmap+1
lda #0
sta y
b1:

View File

@ -193,9 +193,10 @@ main: {
ldx current_ypos
lda current_xpos
sta current_xpos_119
lda current_piece_gfx
ldy play_spawn_current._7
lda PIECES,y
sta current_piece_gfx_112
lda current_piece_gfx+1
lda PIECES+1,y
sta current_piece_gfx_112+1
lda current_piece_char
sta current_piece_char_100
@ -205,10 +206,15 @@ main: {
ldx play_spawn_current.piece_idx
lda #$20
jsr render_next
lda current_piece_gfx
ldy play_spawn_current._7
lda PIECES,y
sta current_piece
lda current_piece_gfx+1
lda PIECES+1,y
sta current_piece+1
lda PIECES,y
sta current_piece_gfx
lda PIECES+1,y
sta current_piece_gfx+1
lda #0
sta level_bcd
sta level
@ -390,8 +396,8 @@ render_bcd: {
render_next: {
// Find the screen area
.const next_area_offset = $28*$c+$18+4
.label next_piece_gfx = 5
.label next_piece_char = $a
.label next_piece_gfx = 5
.label screen_next_area = 7
.label l = 9
cmp #0
@ -409,14 +415,13 @@ render_next: {
b2:
txa
asl
// Render the next piece
tay
lda PIECES_NEXT_CHARS,x
sta next_piece_char
lda PIECES,y
sta next_piece_gfx
lda PIECES+1,y
sta next_piece_gfx+1
lda PIECES_NEXT_CHARS,x
sta next_piece_char
lda #0
sta l
b3:
@ -817,10 +822,15 @@ play_move_down: {
tax
jsr play_update_score
jsr play_spawn_current
lda current_piece_gfx
ldy play_spawn_current._7
lda PIECES,y
sta current_piece
lda current_piece_gfx+1
lda PIECES+1,y
sta current_piece+1
lda PIECES,y
sta current_piece_gfx
lda PIECES+1,y
sta current_piece_gfx+1
lda #0
sta current_orientation
b11:
@ -838,16 +848,13 @@ play_move_down: {
// Spawn a new piece
// Moves the next piece into the current and spawns a new next piece
play_spawn_current: {
.label _7 = 4
.label piece_idx = $21
// Move next piece into current
ldx next_piece_idx
txa
asl
tay
lda PIECES,y
sta current_piece_gfx
lda PIECES+1,y
sta current_piece_gfx+1
sta _7
lda PIECES_CHARS,x
sta current_piece_char
lda PIECES_START_X,x
@ -858,9 +865,10 @@ play_spawn_current: {
sta play_collision.xpos
lda current_ypos
sta play_collision.ypos
lda current_piece_gfx
ldy _7
lda PIECES,y
sta current_piece_100
lda current_piece_gfx+1
lda PIECES+1,y
sta current_piece_100+1
ldx #0
jsr play_collision

View File

@ -17,7 +17,7 @@ main: {
// Test different signed byte constants
test_sbytes: {
.const bb = 0
.const bc = bb+2
.const bc = 2
.const bf = $ff&-$7f-$7f
.const bd = bc-4
.const be = -bd
@ -147,7 +147,7 @@ print_ln: {
// Test different byte constants
test_bytes: {
.const bb = 0
.const bc = bb+2
.const bc = 2
.const bd = bc-4
lda #<$400
sta print_line_cursor

View File

@ -10,7 +10,6 @@ main: {
rts
}
f1: {
.label x = 0
.label return = f2.return+1
jsr f2
rts
@ -501,7 +500,7 @@ f98: {
rts
}
f99: {
.label return = f1.x+1
.label return = 1
jsr f100
rts
}

View File

@ -97,7 +97,7 @@ anim: {
cmp RASTER
bne b4
inc BORDERCOL
ldy sx
ldx sx
jsr calculate_matrix
jsr store_matrix
lda #0
@ -129,13 +129,13 @@ anim: {
tya
asl
tax
lda xp
lda #$80
clc
adc #$80
adc xp
sta SPRITES_XPOS,x
lda yp
lda #$80
clc
adc #$80
adc yp
sta SPRITES_YPOS,x
inc i
lda #8
@ -335,7 +335,8 @@ print_sbyte_at: {
.label at = 6
cpx #0
bmi b1
ldy #' '
lda #' '
sta print_char_at.ch
jsr print_char_at
b2:
inc print_byte_at.at
@ -345,7 +346,8 @@ print_sbyte_at: {
jsr print_byte_at
rts
b1:
ldy #'-'
lda #'-'
sta print_char_at.ch
jsr print_char_at
txa
eor #$ff
@ -355,16 +357,17 @@ print_sbyte_at: {
jmp b2
}
// Print a single char
// print_char_at(byte register(Y) ch, byte* zeropage(6) at)
// print_char_at(byte zeropage(8) ch, byte* zeropage(6) at)
print_char_at: {
.label at = 6
tya
.label ch = 8
lda ch
ldy #0
sta (at),y
rts
}
// Print a byte as HEX at a specific position
// print_byte_at(byte register(X) b, byte* zeropage(6) at)
// print_byte_at(byte* zeropage(6) at)
print_byte_at: {
.label at = 6
txa
@ -374,7 +377,7 @@ print_byte_at: {
lsr
tay
lda print_hextab,y
tay
sta print_char_at.ch
jsr print_char_at
lda #$f
axs #0
@ -382,7 +385,8 @@ print_byte_at: {
bne !+
inc print_char_at.at+1
!:
ldy print_hextab,x
lda print_hextab,x
sta print_char_at.ch
jsr print_char_at
rts
}
@ -390,10 +394,10 @@ print_byte_at: {
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
// rotate_matrix(signed byte register(X) x, signed byte zeropage(5) y, signed byte zeropage($a) z)
// rotate_matrix(signed byte register(X) x, signed byte zeropage(5) y, signed byte zeropage(8) z)
rotate_matrix: {
.label y = 5
.label z = $a
.label z = 8
txa
sta xr
lda y
@ -533,62 +537,61 @@ store_matrix: {
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// calculate_matrix(signed byte register(Y) sx, signed byte zeropage(3) sy)
// calculate_matrix(signed byte register(X) sx, signed byte zeropage(3) sy)
calculate_matrix: {
.label sy = 3
.label t1 = 4
.label t3 = 5
.label t4 = $a
.label t5 = $b
.label t6 = $c
.label t7 = $d
.label t8 = $e
.label t9 = $f
.label t10 = $10
lax sy
axs #sz
stx t1
ldx sy
sty t3
tya
sec
sbc #sz
sta t4
.label t2 = 5
.label t3 = 8
.label t4 = $b
.label t5 = $c
.label t6 = $d
.label t7 = $e
.label t8 = $f
.label t9 = $10
lda sy
sta t1
lda sy
sta t2
stx t3
stx t4
txa
sty $ff
clc
adc $ff
adc t2
sta t5
tya
txa
sec
sbc t1
sta t6
tya
txa
clc
adc t1
sta t7
txa
sty $ff
eor #$ff
sec
sbc $ff
adc t2
sta t8
tya
txa
eor #$ff
sec
adc sy
sta t9
tya
txa
clc
adc sy
sta t10
lda COSH,x
tax
ldy t1
lda COSH,y
ldy t2
clc
adc COSH,y
sta rotation_matrix
ldy t1
lda SINH,y
ldy t2
sec
sbc SINH,x
sbc SINH,y
sta rotation_matrix+1
ldy sy
clc
@ -633,9 +636,8 @@ calculate_matrix: {
sta rotation_matrix+4
ldy t9
lda SINH,y
ldy t10
sec
sbc SINH,y
sbc SINH,x
sta rotation_matrix+5
ldy t4
lda COSH,y
@ -673,9 +675,8 @@ calculate_matrix: {
sec
sbc COSQ,y
sta rotation_matrix+7
lda COSH,x
ldy t9
lda COSH,y
ldy t10
clc
adc COSH,y
sta rotation_matrix+8
@ -954,9 +955,9 @@ debug_print_init: {
str11: .text "yp@"
}
// Print a string at a specific screen position
// print_str_at(byte* zeropage(6) str, byte* zeropage(8) at)
// print_str_at(byte* zeropage(6) str, byte* zeropage(9) at)
print_str_at: {
.label at = 8
.label at = 9
.label str = 6
b1:
ldy #0

View File

@ -184,7 +184,6 @@ bitmap_line_xdyi: {
}
// bitmap_plot(byte register(X) x, byte register(Y) y)
bitmap_plot: {
.label _0 = 9
.label plotter_x = 9
.label plotter_y = $b
.label plotter = 9
@ -196,13 +195,13 @@ bitmap_plot: {
sta plotter_y+1
lda bitmap_plot_ylo,y
sta plotter_y
lda _0
lda plotter
clc
adc plotter_y
sta _0
lda _0+1
sta plotter
lda plotter+1
adc plotter_y+1
sta _0+1
sta plotter+1
lda bitmap_plot_bit,x
ldy #0
ora (plotter),y
@ -336,11 +335,10 @@ init_screen: {
bitmap_clear: {
.label bitmap = 9
.label y = 2
.label _3 = 9
lda bitmap_plot_xlo
sta _3
sta bitmap
lda bitmap_plot_xhi
sta _3+1
sta bitmap+1
lda #0
sta y
b1:

View File

@ -145,11 +145,10 @@ print_char_at: {
rts
}
// Print a byte as HEX at a specific position
// print_byte_at(byte zeropage($a) b, byte* zeropage(8) at)
// print_byte_at(byte* zeropage(8) at)
print_byte_at: {
.label b = $a
.label at = 8
lda b
lda print_sbyte_at.b
lsr
lsr
lsr
@ -159,7 +158,7 @@ print_byte_at: {
sta print_char_at.ch
jsr print_char_at
lda #$f
and b
and print_sbyte_at.b
tay
inc print_char_at.at
bne !+

View File

@ -27,16 +27,10 @@ main: {
rts
}
anim: {
.label _4 = 5
.label _6 = 5
.label _9 = 5
.label _10 = 5
.label _11 = 5
.label _12 = 5
.label cos_a = $b
.label sin_a = $c
.label x = $d
.label y = $e
.label x = $b
.label y = $c
.label xr = 7
.label yr = 9
.label xpos = 5
@ -50,11 +44,6 @@ anim: {
cmp RASTER
bne b2
inc BORDERCOL
ldy angle
lda COS,y
sta cos_a
lda SIN,y
sta sin_a
lda #0
sta sprite_msb
sta i
@ -65,25 +54,27 @@ anim: {
// signed fixed[7.0]
lda ys,y
sta y
lda cos_a
ldy angle
lda COS,y
jsr mulf8u_prepare
ldy x
jsr mulf8s_prepared
lda _4
lda mulf8s_prepared.m
asl
sta xr
lda _4+1
lda mulf8s_prepared.m+1
rol
sta xr+1
ldy y
jsr mulf8s_prepared
lda _6
lda mulf8s_prepared.m
asl
sta yr
lda _6+1
lda mulf8s_prepared.m+1
rol
sta yr+1
lda sin_a
ldy angle
lda SIN,y
jsr mulf8u_prepare
ldy y
jsr mulf8s_prepared
@ -156,44 +147,34 @@ anim: {
// mulf8s_prepared(signed byte register(Y) b)
mulf8s_prepared: {
.label memA = $fd
.label _8 = $f
.label _12 = $f
.label m = 5
.label return = 5
tya
jsr mulf8u_prepared
lda memA
cmp #0
bpl b1
lda m+1
sta _8
tya
eor #$ff
sty $ff
sec
adc _8
sbc $ff
sta m+1
b1:
cpy #0
bpl b2
lda m+1
sta _12
lda memA
eor #$ff
sec
adc _12
sbc memA
sta m+1
b2:
rts
}
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
// mulf8u_prepared(byte register(A) b)
mulf8u_prepared: {
.label resL = $fe
.label memB = $ff
.label return = 5
sta memB
tax
sty memB
ldx memB
sec
sm1:
lda mulf_sqr1_lo,x

View File

@ -120,8 +120,8 @@ loop: {
render_logo: {
.label _3 = $f
.label xpos = 9
.label x_char = 4
.label logo_idx = 4
.label logo_start = 4
lda xpos
and #7
ora #VIC_MCM
@ -142,21 +142,20 @@ render_logo: {
ror _3+1
ror _3
lda _3
tax
sta x_char
lda xpos+1
bmi b1
stx logo_start
ldy #0
b3:
cpy logo_start
bne b4
b2:
cpy x_char
bne b3
lda #0
sta logo_idx
b6:
b5:
cpy #$28
bne b7
bne b6
rts
b7:
b6:
lda logo_idx
sta SCREEN,y
lda #$28*1
@ -181,8 +180,8 @@ render_logo: {
sta SCREEN+$28*5,y
iny
inc logo_idx
jmp b6
b4:
jmp b5
b3:
lda #0
sta SCREEN,y
sta SCREEN+$28*1,y
@ -191,23 +190,23 @@ render_logo: {
sta SCREEN+$28*4,y
sta SCREEN+$28*5,y
iny
jmp b3
jmp b2
b1:
txa
lda x_char
eor #$ff
clc
adc #1
sta logo_idx
ldy #0
b9:
b8:
lda #$28
cmp logo_idx
bne b10
b12:
bne b9
b11:
cpy #$28
bne b13
bne b12
rts
b13:
b12:
lda #0
sta SCREEN,y
sta SCREEN+$28*1,y
@ -216,8 +215,8 @@ render_logo: {
sta SCREEN+$28*4,y
sta SCREEN+$28*5,y
iny
jmp b12
b10:
jmp b11
b9:
lda logo_idx
sta SCREEN,y
lda #$28*1
@ -242,7 +241,7 @@ render_logo: {
sta SCREEN+$28*5,y
iny
inc logo_idx
jmp b9
jmp b8
}
// Generate signed word sinus table - with values in the range min-max.
// sintab - the table to generate into
@ -254,8 +253,7 @@ sin16s_gen2: {
.label ampl = max-min
.label _5 = $b
.label _6 = $f
.label _8 = $f
.label step = $19
.label step = $1b
.label sintab = 2
.label x = 5
.label i = 9
@ -289,10 +287,10 @@ sin16s_gen2: {
lda _5+3
sta _6+1
ldy #0
lda _8
lda _6
sta (sintab),y
iny
lda _8+1
lda _6+1
sta (sintab),y
lda #SIZEOF_SIGNED_WORD
clc
@ -330,13 +328,13 @@ sin16s_gen2: {
}
// Multiply of two signed words to a signed double word
// Fixes offsets introduced by using unsigned multiplication
// mul16s(signed word zeropage($f) a)
// mul16s(signed word zeropage($17) a)
mul16s: {
.label _9 = $f
.label _16 = $f
.label m = $b
.label return = $b
.label a = $f
.label a = $17
lda a
sta mul16u.a
lda a+1
@ -423,18 +421,17 @@ mul16u: {
// sin16s(dword zeropage($b) x)
sin16s: {
.label _4 = $b
.label _20 = $f
.label x = $b
.label return = $f
.label x1 = $1d
.label x2 = $17
.label x3 = $17
.label return = $17
.label x1 = $1f
.label x2 = $19
.label x3 = $19
.label x3_6 = $f
.label usinx = $1f
.label x4 = $17
.label usinx = $17
.label x4 = $19
.label x5 = $f
.label x5_128 = $f
.label sinx = $f
.label sinx = $17
.label isUpper = 4
lda x+3
cmp #>PI_u4f28>>$10
@ -580,17 +577,9 @@ sin16s: {
lda usinx+1
adc x5_128+1
sta usinx+1
lda usinx
sta sinx
lda usinx+1
sta sinx+1
lda isUpper
cmp #0
beq b3
lda usinx
sta _20
lda usinx+1
sta _20+1
sec
lda sinx
eor #$ff
@ -605,15 +594,15 @@ sin16s: {
}
// Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result.
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
// mulu16_sel(word zeropage($17) v1, word zeropage($f) v2, byte register(X) select)
// mulu16_sel(word zeropage($19) v1, word zeropage($f) v2, byte register(X) select)
mulu16_sel: {
.label _0 = $b
.label _1 = $b
.label v1 = $17
.label v1 = $19
.label v2 = $f
.label return = $f
.label return_1 = $17
.label return_10 = $17
.label return_1 = $19
.label return_10 = $19
lda v1
sta mul16u.a
lda v1+1
@ -647,7 +636,7 @@ mulu16_sel: {
div32u16u: {
.label quotient_hi = $11
.label quotient_lo = $f
.label return = $19
.label return = $1b
lda #<PI2_u4f28>>$10
sta divr16u.dividend
lda #>PI2_u4f28>>$10

View File

@ -176,7 +176,6 @@ render_sine: {
bitmap_plot: {
.label _1 = $10
.label plotter = 6
.label plotter_1 = $10
.label x = 4
.label _3 = 6
lda bitmap_plot_yhi,x
@ -189,19 +188,19 @@ bitmap_plot: {
lda x+1
and #>$fff8
sta _1+1
lda plotter_1
lda plotter
clc
adc plotter
sta plotter_1
lda plotter_1+1
adc plotter+1
sta plotter_1+1
adc _1
sta plotter
lda plotter+1
adc _1+1
sta plotter+1
lda x
tay
lda bitmap_plot_bit,y
ldy #0
ora (plotter_1),y
sta (plotter_1),y
ora (plotter),y
sta (plotter),y
rts
}
// wrap_y(signed word zeropage(6) y)
@ -250,8 +249,7 @@ sin16s_gen2: {
.label ampl = max-min
.label _5 = $c
.label _6 = 6
.label _8 = 6
.label step = $19
.label step = $1b
.label sintab = 2
.label x = 8
.label i = 4
@ -285,10 +283,10 @@ sin16s_gen2: {
lda _5+3
sta _6+1
ldy #0
lda _8
lda _6
sta (sintab),y
iny
lda _8+1
lda _6+1
sta (sintab),y
lda #SIZEOF_SIGNED_WORD
clc
@ -326,13 +324,13 @@ sin16s_gen2: {
}
// Multiply of two signed words to a signed double word
// Fixes offsets introduced by using unsigned multiplication
// mul16s(signed word zeropage(6) a)
// mul16s(signed word zeropage($17) a)
mul16s: {
.label _9 = 6
.label _16 = 6
.label m = $c
.label return = $c
.label a = 6
.label a = $17
lda a
sta mul16u.a
lda a+1
@ -419,18 +417,17 @@ mul16u: {
// sin16s(dword zeropage($c) x)
sin16s: {
.label _4 = $c
.label _20 = 6
.label x = $c
.label return = 6
.label x1 = $1d
.label x2 = $17
.label x3 = $17
.label return = $17
.label x1 = $1f
.label x2 = $19
.label x3 = $19
.label x3_6 = 6
.label usinx = $1f
.label x4 = $17
.label usinx = $17
.label x4 = $19
.label x5 = 6
.label x5_128 = 6
.label sinx = 6
.label sinx = $17
.label isUpper = $16
lda x+3
cmp #>PI_u4f28>>$10
@ -576,17 +573,9 @@ sin16s: {
lda usinx+1
adc x5_128+1
sta usinx+1
lda usinx
sta sinx
lda usinx+1
sta sinx+1
lda isUpper
cmp #0
beq b3
lda usinx
sta _20
lda usinx+1
sta _20+1
sec
lda sinx
eor #$ff
@ -601,15 +590,15 @@ sin16s: {
}
// Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result.
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
// mulu16_sel(word zeropage($17) v1, word zeropage(6) v2, byte register(X) select)
// mulu16_sel(word zeropage($19) v1, word zeropage(6) v2, byte register(X) select)
mulu16_sel: {
.label _0 = $c
.label _1 = $c
.label v1 = $17
.label v1 = $19
.label v2 = 6
.label return = 6
.label return_1 = $17
.label return_10 = $17
.label return_1 = $19
.label return_10 = $19
lda v1
sta mul16u.a
lda v1+1
@ -643,7 +632,7 @@ mulu16_sel: {
div32u16u: {
.label quotient_hi = $10
.label quotient_lo = 6
.label return = $19
.label return = $1b
lda #<PI2_u4f28>>$10
sta divr16u.dividend
lda #>PI2_u4f28>>$10

View File

@ -14,9 +14,8 @@ main: {
// puta(byte register(A) ph, byte register(X) pl)
puta: {
.label screen = 2
.label _1 = 2
sta _1+1
stx _1
sta screen+1
stx screen
lda #'a'
ldy #0
sta (screen),y

View File

@ -8,15 +8,14 @@ main: {
.label PTR = $9ffe
.label SCREEN = $400
.label ptr = 2
.label _6 = 2
lda #<STRING
sta PTR
lda #>STRING
sta PTR+1
lda PTR
sta _6
sta ptr
lda PTR+1
sta _6+1
sta ptr+1
ldy #0
lda (ptr),y
sta SCREEN

View File

@ -4,7 +4,6 @@
.label SCREEN = $400
main: {
.label w = 3
.label sc = 3
.label h = 2
lda #0
sta h
@ -18,7 +17,7 @@ main: {
stx w
lda #'*'
ldy #0
sta (sc),y
sta (w),y
inx
cpx #8
bne b2

View File

@ -80,38 +80,34 @@ bitmap_plot: {
.label _1 = 7
.label x = 3
.label plotter = 5
.label plotter_1 = 7
.label _3 = 5
lda bitmap_plot_yhi,x
sta _3+1
sta plotter+1
lda bitmap_plot_ylo,x
sta _3
sta plotter
lda x
and #<$fff8
sta _1
lda x+1
and #>$fff8
sta _1+1
lda plotter_1
lda plotter
clc
adc plotter
sta plotter_1
lda plotter_1+1
adc plotter+1
sta plotter_1+1
adc _1
sta plotter
lda plotter+1
adc _1+1
sta plotter+1
lda x
tay
lda bitmap_plot_bit,y
ldy #0
ora (plotter_1),y
sta (plotter_1),y
ora (plotter),y
sta (plotter),y
rts
}
// Initialize the points to be animated
// point_init(byte zeropage(2) point_idx)
point_init: {
.label _0 = 9
.label _1 = 3
.label _3 = 7
.label _4 = 3
.label _9 = 3
@ -119,29 +115,19 @@ point_init: {
.label _11 = 3
.label point_idx = 2
.label y_diff = 7
.label abs16s1__2 = 3
.label abs16s1_return = 3
.label abs16s2__2 = 5
.label abs16s2_return = 5
.label x_stepf = 3
.label x_diff = 9
lda point_idx
asl
tax
lda x_end,x
sta _0
lda x_end+1,x
sta _0+1
lda x_start,x
sta _1
lda x_start+1,x
sta _1+1
lda x_diff
tay
sec
sbc _1
lda x_end,y
sbc x_start,y
sta x_diff
lda x_diff+1
sbc _1+1
lda x_end+1,y
sbc x_start+1,y
sta x_diff+1
ldy point_idx
lda y_end,y
@ -254,22 +240,22 @@ point_init: {
lda y_diff
eor #$ff
adc #0
sta abs16s2__2
sta abs16s2_return
lda y_diff+1
eor #$ff
adc #0
sta abs16s2__2+1
sta abs16s2_return+1
jmp b6
abs16s1_b1:
sec
lda x_diff
eor #$ff
adc #0
sta abs16s1__2
sta abs16s1_return
lda x_diff+1
eor #$ff
adc #0
sta abs16s1__2+1
sta abs16s1_return+1
jmp abs16s2
}
// Perform division on two signed 16-bit numbers with an initial remainder.
@ -279,9 +265,6 @@ point_init: {
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
// divr16s(signed word zeropage(9) divisor, signed word zeropage(7) rem)
divr16s: {
.label _10 = 7
.label _13 = 9
.label _18 = 3
.label remu = 7
.label divisoru = 9
.label resultu = 3
@ -311,28 +294,28 @@ divr16s: {
rts
b3:
sec
lda _13
lda divisoru
eor #$ff
adc #0
sta _13
lda _13+1
sta divisoru
lda divisoru+1
eor #$ff
adc #0
sta _13+1
sta divisoru+1
tya
eor #1
tay
jmp b4
b1:
sec
lda _10
lda remu
eor #$ff
adc #0
sta _10
lda _10+1
sta remu
lda remu+1
eor #$ff
adc #0
sta _10+1
sta remu+1
ldy #1
jmp b2
}
@ -428,11 +411,10 @@ screen_fill: {
bitmap_clear: {
.label bitmap = 3
.label y = 2
.label _3 = 3
lda bitmap_plot_ylo
sta _3
sta bitmap
lda bitmap_plot_yhi
sta _3+1
sta bitmap+1
lda #0
sta y
b1:

View File

@ -92,13 +92,11 @@ print_sword: {
rts
}
// Print a word as HEX
// print_word(word zeropage(4) w)
print_word: {
.label w = 4
lda w+1
lda print_sword.w+1
sta print_byte.b
jsr print_byte
lda w
lda print_sword.w
sta print_byte.b
jsr print_byte
rts

View File

@ -112,13 +112,11 @@ print_sword: {
rts
}
// Print a word as HEX
// print_word(word zeropage(6) w)
print_word: {
.label w = 6
lda w+1
lda print_sword.w+1
tax
jsr print_byte
lda w
lda print_sword.w
tax
jsr print_byte
rts
@ -180,7 +178,7 @@ print_cls: {
// sin16s_gen(signed word* zeropage(2) sintab)
sin16s_gen: {
.label _1 = 6
.label step = $19
.label step = $1b
.label sintab = 2
.label x = $a
.label i = 4
@ -254,17 +252,16 @@ sin16s_gen: {
// sin16s(dword zeropage($f) x)
sin16s: {
.label _4 = $f
.label _20 = 6
.label x = $f
.label return = 6
.label x1 = $1d
.label x2 = 6
.label x3 = 6
.label x3_6 = 8
.label usinx = $1f
.label x4 = 6
.label x5 = 8
.label x5_128 = 8
.label x1 = $1f
.label x2 = 8
.label x3 = 8
.label x3_6 = $13
.label usinx = 6
.label x4 = 8
.label x5 = $13
.label x5_128 = $13
.label sinx = 6
.label isUpper = $e
lda x+3
@ -411,17 +408,9 @@ sin16s: {
lda usinx+1
adc x5_128+1
sta usinx+1
lda usinx
sta sinx
lda usinx+1
sta sinx+1
lda isUpper
cmp #0
beq b3
lda usinx
sta _20
lda usinx+1
sta _20+1
sec
lda sinx
eor #$ff
@ -436,15 +425,15 @@ sin16s: {
}
// Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result.
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
// mulu16_sel(word zeropage(6) v1, word zeropage(8) v2, byte register(X) select)
// mulu16_sel(word zeropage(8) v1, word zeropage($13) v2, byte register(X) select)
mulu16_sel: {
.label _0 = $f
.label _1 = $f
.label v1 = 6
.label v2 = 8
.label return = 8
.label return_1 = 6
.label return_10 = 6
.label v1 = 8
.label v2 = $13
.label return = $13
.label return_1 = 8
.label return_10 = 8
lda v1
sta mul16u.a
lda v1+1
@ -467,12 +456,12 @@ mulu16_sel: {
rts
}
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
// mul16u(word zeropage($13) a, word zeropage(8) b)
// mul16u(word zeropage($15) a, word zeropage($13) b)
mul16u: {
.label a = $13
.label mb = $15
.label a = $15
.label mb = $17
.label res = $f
.label b = 8
.label b = $13
.label return = $f
lda b
sta mb
@ -524,7 +513,7 @@ mul16u: {
div32u16u: {
.label quotient_hi = 8
.label quotient_lo = 6
.label return = $19
.label return = $1b
lda #<PI2_u4f28>>$10
sta divr16u.dividend
lda #>PI2_u4f28>>$10

View File

@ -129,13 +129,11 @@ print_sword: {
rts
}
// Print a word as HEX
// print_word(word zeropage(8) w)
print_word: {
.label w = 8
lda w+1
lda print_sword.w+1
sta print_byte.b
jsr print_byte
lda w
lda print_sword.w
sta print_byte.b
jsr print_byte
rts
@ -198,8 +196,8 @@ print_cls: {
// wavelength - the number of sinus points in a total sinus wavelength (the size of the table)
// sin16s_genb(signed word* zeropage(2) sintab)
sin16s_genb: {
.label _2 = 6
.label step = $1b
.label _2 = 8
.label step = $1d
.label sintab = 2
.label x = $d
.label i = 4
@ -268,18 +266,17 @@ sin16s_genb: {
// result: signed word sin(x) s[0.15] - using the full range -$7fff - $7fff
// sin16sb(word zeropage(6) x)
sin16sb: {
.label _19 = 6
.label x = 6
.label return = 6
.label return = 8
.label x1 = 6
.label x2 = 8
.label x3 = 8
.label x3_6 = $b
.label usinx = $1f
.label x4 = 8
.label x5 = $b
.label x5_128 = $b
.label sinx = 6
.label x2 = $b
.label x3 = $b
.label x3_6 = $11
.label usinx = 8
.label x4 = $b
.label x5 = $11
.label x5_128 = $11
.label sinx = 8
.label isUpper = $a
lda x+1
cmp #>PI_u4f12
@ -391,17 +388,9 @@ sin16sb: {
lda usinx+1
adc x5_128+1
sta usinx+1
lda usinx
sta sinx
lda usinx+1
sta sinx+1
lda isUpper
cmp #0
beq b3
lda usinx
sta _19
lda usinx+1
sta _19+1
sec
lda sinx
eor #$ff
@ -416,19 +405,19 @@ sin16sb: {
}
// Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result.
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
// mulu16_sel(word zeropage(8) v1, word zeropage($b) v2, byte register(X) select)
// mulu16_sel(word zeropage($b) v1, word zeropage($11) v2, byte register(X) select)
mulu16_sel: {
.label _0 = $13
.label _1 = $13
.label v1 = 8
.label v2 = $b
.label return = 8
.label return_11 = $b
.label return_14 = $b
.label return_16 = $b
.label return_17 = $b
.label return_18 = $b
.label return_20 = $b
.label _0 = $15
.label _1 = $15
.label v1 = $b
.label v2 = $11
.label return = $b
.label return_11 = $11
.label return_14 = $11
.label return_16 = $11
.label return_17 = $11
.label return_18 = $11
.label return_20 = $11
lda v1
sta mul16u.a
lda v1+1
@ -451,13 +440,13 @@ mulu16_sel: {
rts
}
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
// mul16u(word zeropage($11) a, word zeropage($b) b)
// mul16u(word zeropage($13) a, word zeropage($11) b)
mul16u: {
.label a = $11
.label mb = $17
.label res = $13
.label b = $b
.label return = $13
.label a = $13
.label mb = $19
.label res = $15
.label b = $11
.label return = $15
lda b
sta mb
lda b+1
@ -508,7 +497,7 @@ mul16u: {
div32u16u: {
.label quotient_hi = 8
.label quotient_lo = 6
.label return = $1b
.label return = $1d
lda #<PI2_u4f28>>$10
sta divr16u.dividend
lda #>PI2_u4f28>>$10
@ -596,7 +585,7 @@ divr16u: {
// sin16s_gen(signed word* zeropage(2) sintab)
sin16s_gen: {
.label _1 = 6
.label step = $1b
.label step = $1d
.label sintab = 2
.label x = $d
.label i = 4
@ -667,20 +656,19 @@ sin16s_gen: {
// Calculate signed word sinus sin(x)
// x: unsigned dword input u[4.28] in the interval $00000000 - PI2_u4f28
// result: signed word sin(x) s[0.15] - using the full range -$7fff - $7fff
// sin16s(dword zeropage($13) x)
// sin16s(dword zeropage($15) x)
sin16s: {
.label _4 = $13
.label _20 = 6
.label x = $13
.label _4 = $15
.label x = $15
.label return = 6
.label x1 = 6
.label x2 = 8
.label x3 = 8
.label x3_6 = $b
.label usinx = $1f
.label x4 = 8
.label x5 = $b
.label x5_128 = $b
.label x1 = 8
.label x2 = $b
.label x3 = $b
.label x3_6 = $11
.label usinx = 6
.label x4 = $b
.label x5 = $11
.label x5_128 = $11
.label sinx = 6
.label isUpper = $a
lda x+3
@ -827,17 +815,9 @@ sin16s: {
lda usinx+1
adc x5_128+1
sta usinx+1
lda usinx
sta sinx
lda usinx+1
sta sinx+1
lda isUpper
cmp #0
beq b3
lda usinx
sta _20
lda usinx+1
sta _20+1
sec
lda sinx
eor #$ff

View File

@ -11,7 +11,6 @@
.label print_char_cursor = 5
main: {
.label wavelength = $c0
.label _2 = 4
.label sb = 4
jsr sin8s_gen
jsr print_cls
@ -21,11 +20,9 @@ main: {
sta print_char_cursor+1
ldx #0
b1:
lda sintabref,x
sta _2
lda sintab2,x
sec
sbc sb
sbc sintabref,x
sta sb
bmi b2
lda #<str1
@ -107,10 +104,8 @@ print_char: {
rts
}
// Print a byte as HEX
// print_byte(byte zeropage(4) b)
print_byte: {
.label b = 4
lda b
lda print_sbyte.b
lsr
lsr
lsr
@ -119,7 +114,7 @@ print_byte: {
lda print_hextab,y
jsr print_char
lda #$f
and b
and print_sbyte.b
tay
lda print_hextab,y
jsr print_char
@ -175,7 +170,6 @@ sin8s_gen: {
lda x+1
sta sin8s.x+1
jsr sin8s
tya
ldy #0
sta (sintab),y
inc sintab
@ -303,17 +297,16 @@ sin8s: {
bcc b3
dex
b3:
txa
tay
lda isUpper
cmp #0
beq b4
beq b14
txa
eor #$ff
clc
adc #1
tay
b4:
rts
b14:
txa
rts
}
// Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result.

View File

@ -129,10 +129,8 @@ print_char: {
rts
}
// Print a byte as HEX
// print_byte(byte zeropage(4) b)
print_byte: {
.label b = 4
lda b
lda print_sbyte.b
lsr
lsr
lsr
@ -141,7 +139,7 @@ print_byte: {
lda print_hextab,y
jsr print_char
lda #$f
and b
and print_sbyte.b
tay
lda print_hextab,y
jsr print_char
@ -250,17 +248,16 @@ sin16s_gen: {
// sin16s(dword zeropage($b) x)
sin16s: {
.label _4 = $b
.label _20 = $f
.label x = $b
.label return = $f
.label x1 = $1a
.label x2 = $f
.label x3 = $f
.label x3_6 = $11
.label usinx = $20
.label x4 = $f
.label x5 = $11
.label x5_128 = $11
.label x1 = $20
.label x2 = $11
.label x3 = $11
.label x3_6 = $13
.label usinx = $f
.label x4 = $11
.label x5 = $13
.label x5_128 = $13
.label sinx = $f
.label isUpper = 4
lda x+3
@ -407,17 +404,9 @@ sin16s: {
lda usinx+1
adc x5_128+1
sta usinx+1
lda usinx
sta sinx
lda usinx+1
sta sinx+1
lda isUpper
cmp #0
beq b3
lda usinx
sta _20
lda usinx+1
sta _20+1
sec
lda sinx
eor #$ff
@ -432,15 +421,15 @@ sin16s: {
}
// Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result.
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
// mulu16_sel(word zeropage($f) v1, word zeropage($11) v2, byte register(X) select)
// mulu16_sel(word zeropage($11) v1, word zeropage($13) v2, byte register(X) select)
mulu16_sel: {
.label _0 = $b
.label _1 = $b
.label v1 = $f
.label v2 = $11
.label return = $11
.label return_1 = $f
.label return_10 = $f
.label v1 = $11
.label v2 = $13
.label return = $13
.label return_1 = $11
.label return_10 = $11
lda v1
sta mul16u.a
lda v1+1
@ -463,12 +452,12 @@ mulu16_sel: {
rts
}
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
// mul16u(word zeropage($13) a, word zeropage($11) b)
// mul16u(word zeropage($15) a, word zeropage($13) b)
mul16u: {
.label a = $13
.label mb = $15
.label a = $15
.label mb = $17
.label res = $b
.label b = $11
.label b = $13
.label return = $b
lda b
sta mb
@ -629,7 +618,6 @@ sin8s_gen: {
lda x+1
sta sin8s.x+1
jsr sin8s
tya
ldy #0
sta (sintab),y
inc sintab
@ -757,26 +745,25 @@ sin8s: {
bcc b3
dex
b3:
txa
tay
lda isUpper
cmp #0
beq b4
beq b14
txa
eor #$ff
clc
adc #1
tay
b4:
rts
b14:
txa
rts
}
// Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result.
// The select parameter indicates how many of the highest bits of the 16-bit result to skip
// mulu8_sel(byte register(X) v1, byte register(Y) v2, byte zeropage($19) select)
// mulu8_sel(byte register(X) v1, byte register(Y) v2, byte zeropage($1b) select)
mulu8_sel: {
.label _0 = $13
.label _1 = $13
.label select = $19
.label select = $1b
tya
jsr mul8u
ldy select
@ -793,7 +780,7 @@ mulu8_sel: {
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
// mul8u(byte register(X) a, byte register(A) b)
mul8u: {
.label mb = $1a
.label mb = $15
.label res = $13
.label return = $13
sta mb

View File

@ -7,7 +7,7 @@
.const PI_u4f12 = $3244
// PI/2 in u[4.12] format
.const PI_HALF_u4f12 = $1922
.label print_char_cursor = $d
.label print_char_cursor = $f
.label print_line_cursor = 8
main: {
.label tabsize = $14
@ -30,7 +30,6 @@ sin8u_table: {
.const mid = sum/2+1
.label step = $12
.label sinx = $11
.label sinx_sc = $f
.label sintab = 4
.label x = 2
.label i = 6
@ -103,9 +102,10 @@ sin8u_table: {
lda x+1
sta sin8s.x+1
jsr sin8s
sty sinx
sta sinx
tay
jsr mul8su
lda sinx_sc+1
lda mul8su.m+1
tax
axs #-[mid]
txa
@ -142,10 +142,6 @@ sin8u_table: {
lda #>str7
sta print_str.str+1
jsr print_str
lda sinx_sc
sta print_sword.w
lda sinx_sc+1
sta print_sword.w+1
jsr print_sword
lda #<str8
sta print_str.str
@ -264,10 +260,10 @@ print_str: {
jmp b1
}
// Print a signed word as HEX
// print_sword(signed word zeropage($b) w)
// print_sword(signed word zeropage($d) w)
print_sword: {
.label w = $b
lda w+1
.label w = $d
lda mul8su.m+1
bpl b1
lda #'-'
jsr print_char
@ -281,6 +277,10 @@ print_sword: {
adc #0
sta w+1
b1:
lda w
sta print_word.w
lda w+1
sta print_word.w+1
jsr print_word
rts
}
@ -322,8 +322,7 @@ print_sbyte: {
// mul8su(signed byte register(Y) a)
mul8su: {
.const b = sin8u_table.amplitude+1
.label m = $f
.label return = $f
.label m = $d
tya
tax
lda #b
@ -344,8 +343,8 @@ mul8su: {
// mul8u(byte register(X) a, byte register(A) b)
mul8u: {
.label mb = $b
.label res = $f
.label return = $f
.label res = $d
.label return = $d
lda #0
sta res
sta res+1
@ -473,25 +472,24 @@ sin8s: {
bcc b3
dex
b3:
txa
tay
lda isUpper
cmp #0
beq b4
beq b14
txa
eor #$ff
clc
adc #1
tay
b4:
rts
b14:
txa
rts
}
// Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result.
// The select parameter indicates how many of the highest bits of the 16-bit result to skip
// mulu8_sel(byte register(X) v1, byte register(Y) v2, byte zeropage($11) select)
mulu8_sel: {
.label _0 = $f
.label _1 = $f
.label _0 = $d
.label _1 = $d
.label select = $11
tya
sta mul8u.mb

View File

@ -2,7 +2,6 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const SIZEOF_VOID = 0
.const SIZEOF_BYTE = 1
.const SIZEOF_SIGNED_BYTE = 1
.const SIZEOF_BOOL = 1
@ -13,7 +12,7 @@
.const SIZEOF_SIGNED_DWORD = 4
.label SCREEN = $400
main: {
lda #'0'+SIZEOF_VOID
lda #'0'
sta SCREEN
lda #'0'+SIZEOF_BYTE
sta SCREEN+2

View File

@ -2,7 +2,6 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const OFFS_X = 0
.const OFFS_Y = 1
main: {
.label SCREEN = $400
@ -12,7 +11,7 @@ main: {
asl
tay
txa
sta points+OFFS_X,y
sta points,y
txa
clc
adc #4
@ -26,7 +25,7 @@ main: {
tya
asl
tax
lda points+OFFS_X,x
lda points,x
sta SCREEN,y
// SCREEN[i] = points[i].x;
lda points+OFFS_Y,x

View File

@ -2,39 +2,31 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const OFFS_X = 0
.const OFFS_Y = 1
main: {
.label SCREEN = $400
.label _1 = 4
.label _3 = 2
.label _8 = 4
.label _11 = 2
.label point_i = 2
.label point_i1 = 2
ldx #0
b1:
txa
asl
tay
tya
clc
adc #<points
sta point_i
lda #>points
adc #0
sta point_i+1
lda point_i
sta _1
lda point_i+1
sta _1+1
txa
ldy #OFFS_X
sta (_1),y
sta points,y
txa
clc
adc #4
// points[i].x = i;
ldy #OFFS_Y
sta (_3),y
sta (point_i),y
inx
cpx #4
bne b1
@ -42,22 +34,19 @@ main: {
b2:
txa
asl
tay
tya
clc
adc #<points
sta point_i1
lda #>points
adc #0
sta point_i1+1
lda point_i1
sta _8
lda point_i1+1
sta _8+1
ldy #OFFS_X
lda (_8),y
lda points,y
sta SCREEN,x
// SCREEN[i] = points[i].x;
ldy #OFFS_Y
lda (_11),y
lda (point_i1),y
sta SCREEN+$28,x
inx
cpx #4

View File

@ -324,13 +324,11 @@ print_sword: {
rts
}
// Print a word as HEX
// print_word(word zeropage($a) w)
print_word: {
.label w = $a
lda w+1
lda print_sword.w+1
sta print_byte.b
jsr print_byte
lda w
lda print_sword.w
sta print_byte.b
jsr print_byte
rts

View File

@ -216,14 +216,12 @@ div16s: {
divr16s: {
.label _8 = 8
.label _13 = $a
.label _16 = $e
.label _18 = $c
.label dividendu = 8
.label divisoru = $a
.label resultu = $c
.label return = $c
.label dividend = 8
.label divisor = $a
.label dividendu = 8
.label divisoru = $a
lda dividend+1
bmi b1
ldy #0

View File

@ -340,9 +340,7 @@ print_sword: {
// mulf16s(signed word zeropage(3) a, signed word zeropage(5) b)
mulf16s: {
.label _9 = 9
.label _10 = $15
.label _13 = 9
.label _14 = $15
.label _16 = 9
.label _17 = 9
.label m = $11
@ -364,16 +362,12 @@ mulf16s: {
sta _9
lda m+3
sta _9+1
lda b
sta _10
lda b+1
sta _10+1
lda _16
sec
sbc _10
sbc b
sta _16
lda _16+1
sbc _10+1
sbc b+1
sta _16+1
lda _16
sta m+2
@ -386,16 +380,12 @@ mulf16s: {
sta _13
lda m+3
sta _13+1
lda a
sta _14
lda a+1
sta _14+1
lda _17
sec
sbc _14
sbc a
sta _17
lda _17+1
sbc _14+1
sbc a+1
sta _17+1
lda _17
sta m+2
@ -529,30 +519,24 @@ mulf16u: {
// mul16s(signed word zeropage(3) a, signed word zeropage(5) b)
mul16s: {
.label _9 = 9
.label _10 = $15
.label _13 = 9
.label _14 = $15
.label _16 = 9
.label _17 = 9
.label m = $19
.label return = $19
.label a = 3
.label b = 5
lda a
sta mul16u.a
lda a+1
sta mul16u.a+1
lda b
sta mul16u.b
lda b+1
sta mul16u.b+1
lda mul16u.b
sta mul16u.mb
lda mul16u.b+1
lda b+1
sta mul16u.mb+1
lda #0
sta mul16u.mb+2
sta mul16u.mb+3
lda a
sta mul16u.a
lda a+1
sta mul16u.a+1
jsr mul16u
lda a+1
bpl b1
@ -560,16 +544,12 @@ mul16s: {
sta _9
lda m+3
sta _9+1
lda b
sta _10
lda b+1
sta _10+1
lda _16
sec
sbc _10
sbc b
sta _16
lda _16+1
sbc _10+1
sbc b+1
sta _16+1
lda _16
sta m+2
@ -582,16 +562,12 @@ mul16s: {
sta _13
lda m+3
sta _13+1
lda a
sta _14
lda a+1
sta _14+1
lda _17
sec
sbc _14
sbc a
sta _17
lda _17+1
sbc _14+1
sbc a+1
sta _17+1
lda _17
sta m+2
@ -601,14 +577,13 @@ mul16s: {
rts
}
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
// mul16u(word zeropage($1d) a, word zeropage(9) b)
// mul16u(word zeropage(9) a, word zeropage($17) b)
mul16u: {
.label mb = $11
.label a = $1d
.label a = 9
.label res = $19
.label b = 9
.label return = $19
.label b_1 = $17
.label b = $17
lda #0
sta res
sta res+1
@ -796,9 +771,9 @@ mul16u_compare: {
sta mul16u.a
lda a+1
sta mul16u.a+1
lda mul16u.b_1
lda mul16u.b
sta mul16u.mb
lda mul16u.b_1+1
lda mul16u.b+1
sta mul16u.mb+1
lda #0
sta mul16u.mb+2

View File

@ -19,8 +19,6 @@ main: {
// Perform all possible signed byte multiplications (slow and fast) and compare the results
mul8s_compare: {
.label ms = 8
.label mf = $e
.label mn = $c
.label b = 3
.label a = 2
lda #-$80
@ -37,10 +35,10 @@ mul8s_compare: {
ldy b
jsr mul8s
lda ms
cmp mf
cmp mulf8s_prepared.m
bne !+
lda ms+1
cmp mf+1
cmp mulf8s_prepared.m+1
beq b6
!:
ldx #0
@ -49,10 +47,10 @@ mul8s_compare: {
ldx #1
b3:
lda ms
cmp mn
cmp mul8s.m
bne !+
lda ms+1
cmp mn+1
cmp mul8s.m+1
beq b4
!:
ldx #0
@ -129,12 +127,10 @@ print_str: {
!:
jmp b1
}
// mul8s_error(signed byte register(X) a, signed byte zeropage(3) b, signed word zeropage(8) ms, signed word zeropage($c) mn, signed word zeropage($e) mf)
// mul8s_error(signed byte register(X) a, signed byte zeropage(3) b, signed word zeropage(8) ms)
mul8s_error: {
.label b = 3
.label ms = 8
.label mn = $c
.label mf = $e
lda print_line_cursor
sta print_char_cursor
lda print_line_cursor+1
@ -163,9 +159,9 @@ mul8s_error: {
lda #>str3
sta print_str.str+1
jsr print_str
lda mn
lda mul8s.m
sta print_sword.w
lda mn+1
lda mul8s.m+1
sta print_sword.w+1
jsr print_sword
lda #<str4
@ -173,9 +169,9 @@ mul8s_error: {
lda #>str4
sta print_str.str+1
jsr print_str
lda mf
lda mulf8s_prepared.m
sta print_sword.w
lda mf+1
lda mulf8s_prepared.m+1
sta print_sword.w+1
jsr print_sword
jsr print_ln
@ -267,36 +263,28 @@ print_sbyte: {
// Fixes offsets introduced by using unsigned multiplication
// mul8s(signed byte zeropage(2) a, signed byte register(Y) b)
mul8s: {
.label _9 = $10
.label _13 = $10
.label m = $c
.label return = $c
.label a = 2
ldx a
tya
sta mul8u.mb
lda #0
sta mul8u.mb+1
ldx a
jsr mul8u
lda a
cmp #0
bpl b1
lda m+1
sta _9
tya
eor #$ff
sty $ff
sec
adc _9
sbc $ff
sta m+1
b1:
cpy #0
bpl b2
lda m+1
sta _13
lda a
eor #$ff
sec
adc _13
sbc a
sta m+1
b2:
rts
@ -337,44 +325,34 @@ mul8u: {
// Fast multiply two signed bytes to a word result
// mulf8s(signed byte register(A) a, signed byte register(X) b)
mulf8s: {
.label return = $e
jsr mulf8u_prepare
txa
tay
stx mulf8s_prepared.b
jsr mulf8s_prepared
rts
}
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
// mulf8s_prepared(signed byte register(Y) b)
// mulf8s_prepared(signed byte zeropage(3) b)
mulf8s_prepared: {
.label memA = $fd
.label _8 = $10
.label _12 = $10
.label m = $e
.label return = $e
tya
tax
.label b = 3
ldx b
jsr mulf8u_prepared
lda memA
cmp #0
bpl b1
lda m+1
sta _8
tya
eor #$ff
sec
adc _8
sbc b
sta m+1
b1:
cpy #0
lda b
cmp #0
bpl b2
lda m+1
sta _12
lda memA
eor #$ff
sec
adc _12
sbc memA
sta m+1
b2:
rts

View File

@ -102,13 +102,11 @@ print_sword: {
rts
}
// Print a word as HEX
// print_word(word zeropage(6) w)
print_word: {
.label w = 6
lda w+1
lda print_sword.w+1
sta print_byte.b
jsr print_byte
lda w
lda print_sword.w
sta print_byte.b
jsr print_byte
rts

View File

@ -2,10 +2,11 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const b = 3
.const s = 1
main: {
.label screen = $400
lda #3
lda #b
sta screen
lda #s
sta screen+1