Browse Source

first commit

Nikola Kotur 5 months ago
commit
4139326384
40 changed files with 1135 additions and 0 deletions
  1. 69 0
      Examples/01.MusicIrq/MusicIrq.asm
  2. BIN
      Examples/01.MusicIrq/MusicIrq.prg
  3. BIN
      Examples/01.MusicIrq/ode to 64.bin
  4. 41 0
      Examples/02.Simple Scripting/SimpleScripting.asm
  5. BIN
      Examples/02.Simple Scripting/SimpleScripting.prg
  6. 221 0
      Examples/03.Functions Multilabels Fill Virtual/SineAndGraphics.asm
  7. BIN
      Examples/03.Functions Multilabels Fill Virtual/SineAndGraphics.prg
  8. BIN
      Examples/04.Converting Graphics/2x2char.gif
  9. 40 0
      Examples/04.Converting Graphics/Message.asm
  10. BIN
      Examples/04.Converting Graphics/Message.prg
  11. 79 0
      Examples/05.Scoping/Scroll.asm
  12. BIN
      Examples/05.Scoping/Scroll.prg
  13. 46 0
      Examples/06.PseudoCommands/2xSpeedPlayer.asm
  14. BIN
      Examples/06.PseudoCommands/2xSpeedPlayer.prg
  15. BIN
      Examples/06.PseudoCommands/8thFrame.c64
  16. 56 0
      Examples/06.PseudoCommands/8xSpeedPlayer.asm
  17. BIN
      Examples/06.PseudoCommands/8xSpeedPlayer.prg
  18. BIN
      Examples/06.PseudoCommands/DoubleSpeed.c64
  19. 60 0
      Examples/06.PseudoCommands/PseudoCmds.lib
  20. 120 0
      Examples/07.Preprocessor/Preprocessor.asm
  21. BIN
      Examples/07.Preprocessor/Preprocessor.prg
  22. 27 0
      Examples/08.Namespace and libraries/Libs/MyFunctions.lib
  23. 41 0
      Examples/08.Namespace and libraries/Libs/MyIrqRoutines.lib
  24. 22 0
      Examples/08.Namespace and libraries/Libs/MyMacros.lib
  25. 79 0
      Examples/08.Namespace and libraries/Libs/MyPseudoCommands.lib
  26. 4 0
      Examples/08.Namespace and libraries/Libs/MyStdLibs.lib
  27. 25 0
      Examples/08.Namespace and libraries/SimpleSplits.asm
  28. BIN
      Examples/08.Namespace and libraries/SimpleSplits.prg
  29. BIN
      Examples/09.PSID Import/Nightshift.sid
  30. 70 0
      Examples/09.PSID Import/SID_Player.asm
  31. BIN
      Examples/09.PSID Import/SID_Player.prg
  32. 37 0
      Examples/10.Koala Import/KoalaShower.asm
  33. BIN
      Examples/10.Koala Import/KoalaShower.prg
  34. BIN
      Examples/10.Koala Import/picture.prg
  35. 96 0
      Examples/11. Scripting (FloydSteinberg)/FloydSteinberg.asm
  36. BIN
      Examples/11. Scripting (FloydSteinberg)/FloydSteinberg.prg
  37. BIN
      Examples/11. Scripting (FloydSteinberg)/camel.jpg
  38. 2 0
      KickAss.cfg
  39. BIN
      KickAss.jar
  40. BIN
      KickAssembler.pdf

+ 69 - 0
Examples/01.MusicIrq/MusicIrq.asm

@@ -0,0 +1,69 @@
+BasicUpstart2(start)			// <- This creates a basic sys line that can start your program
+
+//----------------------------------------------------------
+//----------------------------------------------------------
+//					Simple IRQ
+//----------------------------------------------------------
+//----------------------------------------------------------
+			* = $4000 "Main Program"		// <- The name 'Main program' will appear in the memory map when assembling
+start:		lda #$00
+			sta $d020
+			sta $d021
+			lda #$00
+			jsr music_init
+			sei
+			lda #$35
+			sta $01
+			lda #<irq1
+			sta $fffe
+			lda #>irq1
+			sta $ffff
+			lda #$1b
+			sta $d011
+			lda #$80
+			sta $d012
+			lda #$81
+			sta $d01a
+			lda #$7f
+			sta $dc0d
+			sta $dd0d
+
+			lda $dc0d
+			lda $dd0d
+			lda #$ff
+			sta $d019
+
+			cli
+			jmp *
+//----------------------------------------------------------
+irq1:  		pha
+			txa
+			pha
+			tya
+			pha
+			lda #$ff
+			sta	$d019
+
+			SetBorderColor(RED)			// <- This is how macros are executed
+			jsr music_play
+			SetBorderColor(BLACK)		// <- There are predefined constants for colors
+
+			pla
+			tay
+			pla
+			tax
+			pla
+			rti
+			
+//----------------------------------------------------------
+			*=$1000 "Music"
+			.label music_init =*			// <- You can define label with any value (not just at the current pc position as in 'music_init:') 
+			.label music_play =*+3			// <- and that is useful here
+			.import binary "ode to 64.bin"	// <- import is used for importing files (binary, source, c64 or text)	
+
+//----------------------------------------------------------
+// A little macro
+.macro SetBorderColor(color) {		// <- This is how macros are defined
+	lda #color
+	sta $d020
+}

BIN
Examples/01.MusicIrq/MusicIrq.prg


BIN
Examples/01.MusicIrq/ode to 64.bin


+ 41 - 0
Examples/02.Simple Scripting/SimpleScripting.asm

@@ -0,0 +1,41 @@
+/**********************************************
+		Simple script demo
+************************************************/
+
+.print "Hello World!"				// <- .print outputs to the console
+.print ""
+
+.print "Lets do a countdown:"
+.for (var i=10; i>0; i--)			// <- For and while loops works like in other programming languages
+	.print i
+.print ""
+
+
+.var x = 10.5						// <- This is how we define variables (we also did it in the for-loop)			
+.const y = 3						// <- y is a constant 
+.print "x*y-5=" + (x*y-5)
+.print ""
+
+.var list = List().add("Bill", "Joe", "Edgar")		// <- We can also use structures like lists and hashtables
+.print "Who is at place number 2:" + list.get(2)
+.print ""
+
+
+// Several commands can be written on the same line by using ';'
+.var a = 10; .var b = 20; .var c = sqrt(pow(a,2)+ pow(b,2))			// <- We also have the entire java math library
+.print "Pythagoras says that c is " + c
+.print ""
+
+.print "Sinus:"
+.var i=0;
+.var spaceStr = "                          ";
+.while (i++<10) {
+	.var x = 5+5*sin(i*2*PI/10)
+	.print spaceStr.substring(0,x)+"o"	
+}
+
+
+
+
+
+

BIN
Examples/02.Simple Scripting/SimpleScripting.prg


+ 221 - 0
Examples/03.Functions Multilabels Fill Virtual/SineAndGraphics.asm

@@ -0,0 +1,221 @@
+:BasicUpstart2(start)
+
+//--------------------------------------------
+// Functions for calculating vic values and other stuff
+// (normally we would put these in a library)
+
+
+.function screenToD018(addr) {										// <- This is how we define a function
+	.return ((addr&$3fff)/$400)<<4
+}
+.function charsetToD018(addr) {
+	.return ((addr&$3fff)/$800)<<1
+}
+.function toD018(screen, charset) {
+	.return screenToD018(screen) | charsetToD018(charset)			//<- This is how we call functions
+}
+
+.function toSpritePtr(addr) {
+	.return (addr&$3fff)/$40
+}
+
+.function sinus(i, amplitude, center, noOfSteps) {
+	.return round(center+amplitude*sin(toRadians(i*360/noOfSteps)))	
+}
+
+
+//--------------------------------------------
+			*=$2000 "Program"
+start: 		sei
+			
+			// Print chars to screen
+			ldx #0
+			lda #5
+!loop: 		sta screen,x			// <- '!' in front of a label means a multilabel (You can have several labels with the same name)
+			sta screen+$100,x
+			sta screen+$200,x
+			sta screen+$300,x
+			sec
+			sbc #1
+			bcs !over+			// <- Referencing forward to the nearest a multilabel called 'over'
+			lda #5				
+!over:
+			inx
+			bne !loop-			// <- Referencing backward to the nearest multilabel called 'loop'
+			
+			
+			lda #toD018(screen, charset)	// <- The d018 value is calculated by a function. You can move graphics around and not worry about d018 is properly set
+			sta $d018							
+			
+			
+			// Setup some sprites
+			lda #$0f
+			sta $d015
+			ldx #7
+!loop:		lda spritePtrs,x
+			sta screen+$3f8,x
+			txa
+			lsr
+			sta $d027,x
+			dex
+			bpl !loop-
+			
+			
+			// Make an effect loop with nonsense sprite movement
+			ldx #0
+			ldy #$0
+			
+!loop: 		lda $d012		// Wait for frame
+			cmp #$ff
+			bne !loop-
+			
+			lda sinus,x		// Set sprite 1
+			sta $d000
+			lda sinus+$40,x
+			sta $d001
+
+
+			lda sinus,x		// Set sprite 2
+			sta $d002
+			lda sinus+$30,y
+			sta $d003
+
+			lda #$f0		// Set sprite 3
+			sta $d004
+			lda sinus,y
+			sta $d005
+
+			lda sinus+$70,x	 // Set sprite 4
+			sta $d006
+			lda sinus,y
+			sta $d007
+	
+			inx
+			iny
+			iny
+			iny
+			jmp !loop-
+
+
+//--------------------------------------------
+			
+spritePtrs:	.byte toSpritePtr(sprite1), toSpritePtr(sprite2)  // <- The spritePtr function is use to calculate the spritePtr
+			.byte toSpritePtr(sprite1), toSpritePtr(sprite2)
+			.byte 0,0,0,0
+
+sinus:		.fill $100, round($a0+$40*sin(toRadians(i*360/$100)))	 	// <- The fill functions takes two argument. 
+																		// The number of bytes to fill and an expression to execute for each
+																		// byte. 'i' is the byte number 
+
+			.fill $100, sinus(i, $40, $a0, $100)			//<- Its easier to use a function when you use the expression many times			
+//--------------------------------------------
+			.align $0800		// <-- You can use align to align data to memory boundaries
+
+charset: 	.byte %11111110
+			.byte %10000010
+			.byte %10000010
+			.byte %10000010
+			.byte %10000010
+			.byte %10000010
+			.byte %11111110
+			.byte %00000000
+			
+			.byte %00000000
+			.byte %01111100
+			.byte %01000100
+			.byte %01000100
+			.byte %01000100
+			.byte %01111100
+			.byte %00000000
+			.byte %00000000
+		
+			.byte %00000000
+			.byte %00000000
+			.byte %00111000
+			.byte %00101000
+			.byte %00111000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+		
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00010000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+		
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+			.byte %00000000
+	
+//--------------------------------------------
+			.align $40	
+sprite1: 	.byte %00000000, %11111111, %00000000 	
+		 	.byte %00000001, %11111111, %10000000 	
+		 	.byte %00000011, %11111111, %11000000 	
+		 	.byte %00000111, %11111111, %11100000 	
+		 	.byte %00001111, %11111111, %11110000 	
+		 	.byte %00011111, %11111111, %11111000 	
+		 	.byte %00111111, %11111111, %11111100 	
+		 	.byte %00000011, %11111111, %11000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+		 	.byte %00000000, %00000000, %00000000 	
+			.byte $00
+
+sprite2:	.byte %01110000, %00000000, %00000000
+			.byte %11111000, %00000000, %00000000
+			.byte %11111000, %00000000, %00000000
+			.byte %01110000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte %00000000, %00000000, %00000000
+			.byte $00
+			
+//--------------------------------------------
+			* = $3c00 "Virtual data" virtual		// <- Data in a virtual block is not entered into memory 
+screen: 	.fill $0400, 0
+			
+	
+	

BIN
Examples/03.Functions Multilabels Fill Virtual/SineAndGraphics.prg


BIN
Examples/04.Converting Graphics/2x2char.gif


+ 40 - 0
Examples/04.Converting Graphics/Message.asm

@@ -0,0 +1,40 @@
+BasicUpstart2(start)
+			* = $1000
+start: 		sei
+
+			jsr $e544
+			lda #$18
+			sta $d018
+			
+			.const target = $0400+8+11*40
+			ldx #0
+			ldy #0			
+loop:		lda text,y
+			cmp #$ff
+			beq exit
+			clc
+			sta target,x
+			adc #$40
+			sta target+40,x
+			inx
+			adc #$40
+			sta target,x
+			adc #$40
+			sta target+40,x
+			inx
+			iny
+			jmp loop
+exit:
+			jmp *						
+
+text: 		.text "hello world.."	
+			.byte $ff
+
+//------------------------------------------------------------------------------------
+			* = $2000 "Charset"
+			.var charsetPic = LoadPicture("2x2char.gif", List().add($000000, $ffffff))   // <- Here we load a gif picture
+			.fill $200, charsetPic.getSinglecolorByte(  2*(i>>3),   i&7) 				 // <- getSinglecolorByte gives a converted singlecolor byte  	
+			.fill $200, charsetPic.getSinglecolorByte(  2*(i>>3), 8+(i&7)) 				 // (You can also get a multicolor byte or a raw value)
+			.fill $200, charsetPic.getSinglecolorByte(1+2*(i>>3),    i&7) 
+			.fill $200, charsetPic.getSinglecolorByte(1+2*(i>>3), 8+(i&7)) 
+			

BIN
Examples/04.Converting Graphics/Message.prg


+ 79 - 0
Examples/05.Scoping/Scroll.asm

@@ -0,0 +1,79 @@
+BasicUpstart2(mainProg)
+
+.const scrollLine = $0400+24*40
+
+//----------------------------------------------------
+// 			Main Program
+//----------------------------------------------------
+			*=$1000
+mainProg: 	{								// <- Here we define a scope
+			sei
+			lda #$17
+			sta $d018
+
+			// Wait for line $f2 and set d016	
+loop1:		lda #$f2							//<- Here we define 'loop1'
+			cmp $d012
+			bne loop1
+			jsr setScrollD016
+			
+			// Wait for line $ff and prepare next frame 
+loop2:		lda #$ff							// <- Inside the scope labels can collide so we use 'loop2'	
+			cmp $d012
+			bne loop2
+			lda #$c8
+			sta $d016
+			jsr moveScroll
+			
+			jmp loop1
+}
+//----------------------------------------------------
+// 			Scroll Routines
+//----------------------------------------------------
+
+setScrollD016:	{
+value:		lda #0									
+			and #$07
+			ora #$c0
+			sta $d016
+			rts			
+}
+
+moveScroll: {
+			// Step d016
+			dec setScrollD016.value+1			//<- We can access labels of other scopes this way!				
+			lda setScrollD016.value+1
+			and #$07
+			cmp #$07
+			bne exit
+			
+			// Move screen chars
+			ldx #0
+loop1:		lda scrollLine+1,x					// <- Since 'loop1' is in a new scope it doesn't collide with the first 'loop1' label 
+			sta scrollLine,x
+			inx
+			cpx #39
+			bne loop1
+			
+			// Print new char
+count:		ldx #0
+			lda text,x
+			sta scrollLine+39	
+			inx 
+			lda text,x
+			cmp #$ff
+			bne over1
+			ldx #0
+over1:		stx count+1
+			
+exit:		rts
+			
+text:		.text "Hello friends, how are we doing today. Hope you enjoy this scoping demo. Now get ready for pseudocommands....   "
+			.byte $ff
+}
+
+
+
+
+
+

BIN
Examples/05.Scoping/Scroll.prg


+ 46 - 0
Examples/06.PseudoCommands/2xSpeedPlayer.asm

@@ -0,0 +1,46 @@
+#import "PseudoCmds.lib"		// <- Look in this file to see how the commands are defined
+BasicUpstart2(start)
+//----------------------------------------------------------
+//----------------------------------------------------------
+//			Double Speed Music player
+//----------------------------------------------------------
+//----------------------------------------------------------	
+			* = $0900 "Main Program"
+start:		sei
+			ldy #$00
+			jsr music_init
+			mov #$35 : $01            // <- Notice how different addressing modes can be used
+			mov16 #irq1 : $fffe		  // <- 16 bit commands (or higher) can also be made
+			mov #$1b : $d011
+			mov #$33 : $d012
+			mov #$81 : $d01a
+			mov #$7f : $dc0d
+			mov #$7f : $dd0d
+			lda $dc0d
+			lda $dd0d
+			mov #$ff : $d019
+			cli
+			jmp *
+
+irq1:  		irqStart				// <- Pseudocmds can be made for standard procedures
+			mov #WHITE : $d020
+			jsr music_play
+			mov #BLACK : $d020
+			irqEnd #$d8 : #irq2 	// <- $d012 and $fffe values are optional
+
+irq2:  		irqStart
+			mov #WHITE : $d020
+			jsr music_play
+			mov #BLACK : $d020
+			irqEnd #$33 : #irq1 
+//----------------------------------------------------------
+			* = $1000 "Music"
+			.label music_init = *
+			.label music_play = *+3
+			.import c64 "DoubleSpeed.c64"
+//----------------------------------------------------------
+
+
+
+
+

BIN
Examples/06.PseudoCommands/2xSpeedPlayer.prg


BIN
Examples/06.PseudoCommands/8thFrame.c64


+ 56 - 0
Examples/06.PseudoCommands/8xSpeedPlayer.asm

@@ -0,0 +1,56 @@
+#import "PseudoCmds.lib"		
+BasicUpstart2(start)
+.const xSpeed = 8
+//----------------------------------------------------------
+//----------------------------------------------------------
+//			8xSpeed Music player								
+//			NOTE.. Check out the 2xSpeedPlayer before this! 	<- NOTE	
+//----------------------------------------------------------
+//----------------------------------------------------------
+			* = $0900 "Main Program"
+start:		sei
+			lda #$00
+			jsr music_init
+			mov #$35 : $01            
+			mov16 #irq1 : $fffe		 
+			mov #$1b : $d011
+			mov #$33 : $d012
+			mov #$81 : $d01a
+			mov #$7f : $dc0d
+			mov #$7f : $dd0d
+			lda $dc0d
+			lda $dd0d
+			mov #$ff : $d019
+			cli
+			jmp *
+
+irq1:  		irqStart				
+
+			incLim frameNo : #xSpeed 	// <- Increase with wraplimit. But know your commands, this is not that fast
+			ldx frameNo
+			mov intPlay,x : playJsr+1	// <- Notice how all addressing modes can be used for a pseudo cmds (Also ,x ,y (zp),y etc) 
+			mov #WHITE : $d020
+playJsr:	jsr music_play
+			mov #BLACK : $d020
+
+			ldx frameNo
+			mov intD011,x : $d011	
+			irqEnd intD012,x		// <- Notice the address of the next irq is not given (its optional) 	
+
+frameNo:	.byte 0
+
+intPlay:	.byte <music_play, <music_play+3, <music_play+3,<music_play+3,<music_play+3,<music_play+3,<music_play+3,<music_play+6
+intD012:	.fill xSpeed, i*312/xSpeed
+intD011:	.fill xSpeed, $1b + (((i*312/xSpeed)&$100)>>1)
+
+//----------------------------------------------------------
+			* = $1000 "Music"
+			.label music_init = *
+			.label music_play = *+3
+			.import c64 "8thFrame.c64"
+//----------------------------------------------------------
+
+
+
+
+

BIN
Examples/06.PseudoCommands/8xSpeedPlayer.prg


BIN
Examples/06.PseudoCommands/DoubleSpeed.c64


+ 60 - 0
Examples/06.PseudoCommands/PseudoCmds.lib

@@ -0,0 +1,60 @@
+#importonce
+
+//------------------------------------
+// Basic commands
+//------------------------------------
+.pseudocommand mov arg1:arg2 {
+	lda arg1
+	sta arg2
+}
+
+.pseudocommand incLim tar:lim {
+	inc tar
+	lda tar
+	cmp lim
+	bne exit
+	lda #0
+	sta tar	
+exit:
+}
+
+
+
+.pseudocommand mov16 src:tar {
+	lda src
+	sta tar
+	lda _16bit_nextArgument(src)
+	sta _16bit_nextArgument(tar)
+}
+
+.function _16bit_nextArgument(arg) {
+	.if (arg.getType()==AT_IMMEDIATE) .return CmdArgument(arg.getType(),>arg.getValue())
+	.return CmdArgument(arg.getType(),arg.getValue()+1)
+}
+
+
+
+
+//------------------------------------
+// Irq commands
+//------------------------------------
+.pseudocommand irqStart {
+		pha
+		txa
+		pha
+		tya
+		pha
+		mov #$ff : $d019
+}
+
+.pseudocommand irqEnd line : addr {
+		.if (line.getType()!=AT_NONE) 	mov line : $d012
+		.if (addr.getType()!=AT_NONE) 	mov addr : $fffe
+		pla
+		tay
+		pla
+		tax
+		pla
+		rti
+}
+

+ 120 - 0
Examples/07.Preprocessor/Preprocessor.asm

@@ -0,0 +1,120 @@
+
+#define IRQ_UNDER_ROM	// <- here we define a preprocesssor symbol. This can also be done
+#define STANDALONE
+
+//-----------------------------------------------------
+// Upstart program if we are in stand alone mode
+//-----------------------------------------------------
+
+#if STANDALONE		// <- The source inside the #if is discarded if STANDALONE is not defined
+			BasicUpstart2(start)
+start:		sei
+	
+	#if !IRQ_UNDER_ROM		//	<- If's can be nested. Notice the ! operator. Other operators are ==, !=, ||, && and () 
+				lda #<irq1
+				sta $0314
+				lda #>irq1
+				sta $0315
+	#else
+				lda #$35
+				sta $01
+				lda #<irq1
+				sta $fffe
+				lda #>irq1
+				sta $ffff
+	#endif	
+
+			lda #$1b
+			sta $d011
+			lda #$32
+			sta $d012
+			lda #$81
+			sta $d01a
+			lda #$7f
+			sta $dc0d
+			sta $dd0d
+
+			lda $dc0d
+			lda $dd0d
+			lda #$ff
+			sta $d019
+			cli
+			inc $d020
+			jmp *
+#endif
+
+
+
+//-----------------------------------------------------
+// Procedures for start and end of interupt
+//-----------------------------------------------------
+
+#if !IRQ_UNDER_ROM 
+
+	.pseudocommand irqStart {  // <- Since preprocessor commands are executed before anything else, you can redefined macros, functions, imports etc dependant on your settings
+							   // (This can't be done by normal .if directives)
+				lda #$ff
+				sta $d019
+	}
+		
+	.pseudocommand irqEnd line : addr {  		 
+				.if (line.getType()!=AT_NONE) {lda line; sta $d012; }	
+				.if (addr.getType()!=AT_NONE) {lda #<addr.getValue(); sta $0314; lda #>addr.getValue(); sta $0315; }	
+				jmp $ea81
+	}
+#else
+	.pseudocommand irqStart {
+				pha
+				txa
+				pha
+				tya
+				pha
+				lda #$ff
+				sta $d019
+	}
+
+
+	.pseudocommand irqEnd line : addr {
+				.if (line.getType()!=AT_NONE) {lda line; sta $d012; }	
+				.if (addr.getType()!=AT_NONE) {lda #<addr.getValue(); sta $fffe; lda #>addr.getValue(); sta $ffff; }	
+				pla
+				tay
+				pla
+				tax
+				pla
+				rti
+	}
+#endif
+		
+	
+
+//-----------------------------------------------------
+// The Irqs
+//-----------------------------------------------------
+#if !IRQ_UNDER_ROM
+			.const delay = 3
+#else
+			.const delay = 7
+#endif
+			*=$5000
+irq1:  		irqStart
+			ldy #delay
+			dey
+			bne *-1
+			lda #LIGHT_BLUE
+			sta $d020
+			irqEnd #$32+200 : #irq2
+
+
+irq2:  		irqStart
+			ldy #delay
+			dey
+			bne *-1
+			lda #BLACK
+			sta $d020
+			irqEnd #$32 : #irq1
+
+
+
+ 
+ 

BIN
Examples/07.Preprocessor/Preprocessor.prg


+ 27 - 0
Examples/08.Namespace and libraries/Libs/MyFunctions.lib

@@ -0,0 +1,27 @@
+#importonce					// <-- This is a library, we only want it included once
+.filenamespace MyFunctions	// <-- Sets up a 'MyFunctions' namespace for this file
+
+//-----------------------------
+// Help functions 
+//-----------------------------
+
+.function failOnOverflow(x, limit) { //<-- This function can only be seen within the MyFunctions namespace
+	.if (x>=limit)
+		.error("value too high: " + x) 
+
+	.if (x<0)
+		.error("value too low:x " + x) 
+}
+
+//-----------------------------
+// Library functions 
+//-----------------------------
+.function @toSpritePtr(addr) { 		// <-- @ puts this function in the root scope so everyone can see it
+	.eval failOnOverflow(addr,$10000)
+	.return (addr&$3fff)/$40
+}
+
+
+
+
+ 

+ 41 - 0
Examples/08.Namespace and libraries/Libs/MyIrqRoutines.lib

@@ -0,0 +1,41 @@
+#importonce 
+#import "MyPseudoCommands.lib"
+.filenamespace DemoSetup
+
+
+//-----------------------------
+// IrqHelp functions 
+//-----------------------------
+.pseudocommand @setupIrq line : address {
+		sei
+		mov #$35 : $01            
+		mov16 address : $fffe		 
+		mov #$1b : $d011
+		mov line : $d012
+		mov #$81 : $d01a
+		mov #$7f : $dc0d
+		mov #$7f : $dd0d
+		lda $dc0d
+		lda $dd0d
+		mov #$ff : $d019
+		cli
+}
+.pseudocommand @irqStart {
+		pha
+		txa
+		pha
+		tya
+		pha
+		mov #$ff : $d019
+}
+
+.pseudocommand @irqEnd line : addr {
+		.if (line.getType()!=AT_NONE) 	mov line : $d012
+		.if (addr.getType()!=AT_NONE) 	mov addr : $fffe
+		pla
+		tay
+		pla
+		tax
+		pla
+		rti
+}

+ 22 - 0
Examples/08.Namespace and libraries/Libs/MyMacros.lib

@@ -0,0 +1,22 @@
+#importonce					// <-- This is a library, we only want it included once
+.filenamespace MyMacros		// <-- Sets up a 'MyMacros' namespace for this file
+
+//-----------------------------
+// Library Macros 
+//-----------------------------
+.macro @ClearScreen(target, clearByte) {  
+	ldx #0
+	lda #clearByte
+loop:
+	sta target,x
+	sta target+$100,x
+	sta target+$200,x
+	sta target+40*25-$100,x
+	inx
+	bne loop
+}
+
+
+
+
+ 

+ 79 - 0
Examples/08.Namespace and libraries/Libs/MyPseudoCommands.lib

@@ -0,0 +1,79 @@
+#importonce							// <-- This is a library, we only want it included once
+.filenamespace MyPseudoCommands		// <-- Sets up a 'MyMacros' namespace for this file
+
+
+//-----------------------------
+// Help functions 
+//-----------------------------
+.function _16bit_nextArgument(arg) { // <-- Not visible in root scope
+	.if (arg.getType()==AT_IMMEDIATE) .return CmdArgument(arg.getType(),>arg.getValue())
+	.return CmdArgument(arg.getType(),arg.getValue()+1)
+}
+
+.macro ensureImmediateArgument(arg) {
+	.if (arg.getType()!=AT_IMMEDIATE)	.error "The argument must be immediate!" 
+}
+
+
+//-----------------------------
+// Library PseudoCommands 
+//-----------------------------
+.pseudocommand @mov arg1:arg2 {   //<-- @ puts it in the root scope
+	lda arg1
+	sta arg2
+}
+
+.pseudocommand @mov16 src:tar {   
+	lda src
+	sta tar
+	lda _16bit_nextArgument(src)
+	sta _16bit_nextArgument(tar)
+}
+
+.pseudocommand @lsr16 arg {
+	lsr _16bit_nextArgument(arg)
+	ror arg
+}
+.pseudocommand @asl16 arg {
+	asl arg
+	rol _16bit_nextArgument(arg)
+}
+
+.pseudocommand @pause cycles {
+	ensureImmediateArgument(cycles)
+	.var x = floor(cycles.getValue())
+	.if (x<2) .error "Cant make a pause on " + x + " cycles"
+
+	// Make a delay loop
+	.if (x>=11) {
+		.const cfirst = 6	// cycles for first loop
+		.const cextra = 5	// cycles for extra loops
+		.var noOfLoops = 1+floor([x-cfirst]/cextra)
+		.eval x = x - cfirst - [noOfLoops-1]*cextra
+		.if (x==1){
+			.eval x=x+cextra
+			.eval noOfLoops--	
+		}
+		ldy #noOfLoops
+m1:		dey
+m2:		bne *-1
+		.if (m1>>8 !=  m2>>8) .error "Pause loop is crossing page. Invalid cycle count!"
+	}
+
+	// Take care of odd cyclecount	
+	.if ([x&1]==1) {
+		bit $00
+		.eval x=x-3
+	}	
+	
+	// Take care of the rest
+	.if (x>0)
+		nop #x/2
+}
+.pseudocommand @nop x {
+	ensureImmediateArgument(x)
+	.for (var i=0; i<x.getValue(); i++) nop
+}
+
+
+

+ 4 - 0
Examples/08.Namespace and libraries/Libs/MyStdLibs.lib

@@ -0,0 +1,4 @@
+#import "MyFunctions.lib"
+#import "MyMacros.lib"
+#import "MyPseudoCommands.lib"
+#import "MyIrqRoutines.lib"

+ 25 - 0
Examples/08.Namespace and libraries/SimpleSplits.asm

@@ -0,0 +1,25 @@
+#import "Libs/MyStdLibs.lib"
+
+BasicUpstart2(start)
+//------------------------------------------
+start: 
+		ClearScreen($0400, ' ')
+		mov #LIGHT_GRAY : $d021
+		setupIrq #$32 : #irq1
+		jmp *
+		
+//------------------------------------------
+irq1:	irqStart
+		pause #32
+		mov #DARK_GRAY : $d020
+		irqEnd #$32+25*8 : #irq2 
+//------------------------------------------
+irq2:	irqStart
+		pause #32
+		mov #GRAY : $d020
+		irqEnd #$32 : #irq1 
+		
+
+//We can't see the help-functions like _16bit_nextArgument since it inside a namespace 
+.asserterror "Testing function visibility", _16bit_nextArgument($1234)  
+		

BIN
Examples/08.Namespace and libraries/SimpleSplits.prg


BIN
Examples/09.PSID Import/Nightshift.sid


+ 70 - 0
Examples/09.PSID Import/SID_Player.asm

@@ -0,0 +1,70 @@
+BasicUpstart2(start)
+//---------------------------------------------------------
+//---------------------------------------------------------
+//			SID Player (Single speed)
+//---------------------------------------------------------
+//---------------------------------------------------------
+			.var music = LoadSid("Nightshift.sid")		//<- Here we load the sid file
+
+start:		lda #$00
+			sta $d020
+			sta $d021
+			ldx #0
+			ldy #0
+			lda #music.startSong-1						//<- Here we get the startsong and init address from the sid file
+			jsr music.init	
+			sei
+			lda #<irq1
+			sta $0314
+			lda #>irq1
+			sta $0315
+			lda #$1b
+			sta $d011
+			lda #$80
+			sta $d012
+			lda #$7f
+			sta $dc0d
+			sta $dd0d
+			lda #$81
+			sta $d01a
+			lda $dc0d
+			lda $dd0d
+			asl $d019
+			cli
+			jmp *
+
+//---------------------------------------------------------
+irq1:  	    asl $d019
+			inc $d020
+			jsr music.play 									// <- Here we get the play address from the sid file
+			dec $d020
+			jmp $ea81
+
+//---------------------------------------------------------
+			*=music.location "Music"
+			.fill music.size, music.getData(i)				// <- Here we put the music in memory
+
+//----------------------------------------------------------
+			// Print the music info while assembling
+			.print ""
+			.print "SID Data"
+			.print "--------"
+			.print "location=$"+toHexString(music.location)
+			.print "init=$"+toHexString(music.init)
+			.print "play=$"+toHexString(music.play)
+			.print "songs="+music.songs
+			.print "startSong="+music.startSong
+			.print "size=$"+toHexString(music.size)
+			.print "name="+music.name
+			.print "author="+music.author
+			.print "copyright="+music.copyright
+
+			.print ""
+			.print "Additional tech data"
+			.print "--------------------"
+			.print "header="+music.header
+			.print "header version="+music.version
+			.print "flags="+toBinaryString(music.flags)
+			.print "speed="+toBinaryString(music.speed)
+			.print "startpage="+music.startpage
+			.print "pagelength="+music.pagelength

BIN
Examples/09.PSID Import/SID_Player.prg


+ 37 - 0
Examples/10.Koala Import/KoalaShower.asm

@@ -0,0 +1,37 @@
+:BasicUpstart2(start)
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//  					KOALA SHOWER
+//
+//This code displays the Koala picture in the file picture.prg
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+			.var picture = LoadBinary("picture.prg", BF_KOALA)
+
+start:  	lda #$38
+			sta $d018
+			lda #$d8
+			sta $d016
+			lda #$3b
+			sta $d011
+			lda #BLACK
+			sta $d020
+			lda #picture.getBackgroundColor()
+			sta $d021
+			ldx #0
+
+loop1:		.for (var i=0; i<4; i++) {
+				lda colorRam+i*$100,x
+				sta $d800+i*$100,x
+			}
+			inx
+			bne loop1
+			jmp *
+
+*=$0c00	"ScreenRam"; 			.fill picture.getScreenRamSize(), picture.getScreenRam(i)
+*=$1c00	"ColorRam:"; colorRam: 	.fill picture.getColorRamSize(), picture.getColorRam(i)
+*=$2000	"Bitmap";				.fill picture.getBitmapSize(), picture.getBitmap(i)
+
+
+
+

BIN
Examples/10.Koala Import/KoalaShower.prg


BIN
Examples/10.Koala Import/picture.prg


+ 96 - 0
Examples/11. Scripting (FloydSteinberg)/FloydSteinberg.asm

@@ -0,0 +1,96 @@
+BasicUpstart2(start)
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// 			Graphic conversion with FloydSteinberg
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+start:	sei
+		lda #$3b
+		sta $d011
+		lda #$18
+		sta $d018
+		lda #BLACK
+		sta $d020
+		ldx #0
+		lda #BLACK | (WHITE<<4)
+loop:	sta $0400,x
+		sta $0500,x
+		sta $0600,x
+		sta $0700,x
+		inx
+		bne loop
+		jmp *
+
+		*=$2000 "Picture"
+		.var pic1 = floydSteinberg("camel.jpg")
+		.fill 40*200, pic1.get(i)
+
+
+//--------------------------------------------------------------------------
+
+.function floydSteinberg(filename) {
+	.var width = 320
+	.var height = 200
+
+	.var picture = LoadPicture(filename)
+
+	// Create intensity map
+	.var intensityMap = List();
+	.var maxInt = $0;
+	.var minInt = $ffffff
+	.for (var y=0; y<height; y++) {
+		.for (var x=0; x<width; x++) {
+			.var rgb = picture.getPixel(x,y)
+			.var intensity = sqrt(pow(rgb&$ff,2) + pow((rgb>>8)&$ff,2) + pow((rgb>>16)&$ff,2))
+			.eval intensityMap.add(intensity)
+			.eval maxInt = max(maxInt, intensity)	
+			.eval minInt = min(minInt, intensity)	
+		}
+		.eval intensityMap.add(0)	// Add extra colunn to catch overflow	
+	}
+	.for (var x=0; x<width+1; x++) 
+		.eval intensityMap.add(0)	// Add extra row to catch overflow
+
+	// Do Floyd-Steinberg dithering
+	.var limit = (maxInt+minInt)/2
+	.for (var y=0; y<height; y++) {
+		.for (var x=0; x<width; x++) {
+			.var int = intensityMap.get(x+y*(width+1))
+			.var selectedPixel = int < limit ? 0 : 1
+			.var selectedIntensity = int < limit ? minInt : maxInt
+			.var error = int - selectedIntensity
+			.eval intensityMap.set(x+y*(width+1), selectedPixel)
+
+			.var idx;
+			.eval idx = (x+1)+(y+0)*(width+1)
+			.eval intensityMap.set(idx, intensityMap.get(idx) + error *7/16)
+			.eval idx = (x-1)+(y+1)*(width+1)
+			.eval intensityMap.set(idx, intensityMap.get(idx) + error *3/16)
+			.eval idx = (x+0)+(y+1)*(width+1)
+			.eval intensityMap.set(idx, intensityMap.get(idx) + error *5/16)
+			.eval idx = (x+1)+(y+1)*(width+1)
+			.eval intensityMap.set(idx, intensityMap.get(idx) + error *1/16) 
+		}
+	}
+	
+	// Convert to byteStream
+	.var result = List()
+	.for (var charY=0; charY<25; charY++) {
+		.for (var charX=0; charX<40; charX++) {
+			.for (var charRow=0;charRow<8; charRow++) {
+				.var byte = 0
+				.var idx = charX*8 + (charY*8+charRow)*(width+1)
+				.for (var pixelNo=0;pixelNo<8; pixelNo++)
+					.eval byte=byte*2+intensityMap.get(idx+pixelNo)
+				.eval result.add(byte)			
+			}
+		}
+	}
+	.return result
+}
+
+
+
+
+

BIN
Examples/11. Scripting (FloydSteinberg)/FloydSteinberg.prg


BIN
Examples/11. Scripting (FloydSteinberg)/camel.jpg


+ 2 - 0
KickAss.cfg

@@ -0,0 +1,2 @@
+-showmem
+-symbolfile

BIN
KickAss.jar


BIN
KickAssembler.pdf