; Only tested on DCPU-16 Studio

; rxi

; ENTRY POINT

: main

jsr reset

set a , welcomestr

jsr printstring

jsr maincmdloop

set pc , halt

: welcomestr dat "Welcome to my test program.

This should maybe work...

Try typing 'help' for a command

list.

" , 0

; GENERAL

; DATA

: randvara dat 0x2351

: randvarb dat 0x1252

; SUB ROUTINES

: halt ; An infinite unescapeable loop

set pc , halt

: rand ; Sets Z register to a 'random' number

set push , a

set push , b

set push , x

set push , y

set a , [ randvara ]

set b , [ randvarb ]

set x , a

and x , 0xFF

mul x , 369

shr a , 8

add a , x

set y , a

and y , 0xFF

mul y , 180

shr b , 8

add b , y

set z , a

shl z , 8

add z , b

set [ randvara ] , a

set [ randvarb ] , b

set y , pop

set x , pop

set b , pop

set a , pop

set pc , pop

; COMMAND

; DATA

: cmdstrerror dat " - Bad cmd.

" , 0

: cmdstrcls dat "cls" , 0

: cmdstrcolor dat "color" , 0

: cmdstrrandom dat "random" , 0

: cmdstrtest dat "test" , 0

: cmdstrhelp dat "help" , 0

: cmdstrrps dat "rps" , 0

; SUB ROUTINES

: cmdtest ; Test command

set push , a

set a , cmdtest_str

jsr printstring

set a , pop

set pc , endcmd

: cmdtest_str dat "Rawwwr!

This is a test command!

" , 0

: cmdhelp ; Help command

set push , a

set a , cmdhelp_str

jsr printstring

set a , pop

set pc , endcmd

: cmdhelp_str dat "Commands:

help, test, random, rps, cls

color

" , 0

: cmdcls ; Clearscreen command

jsr cls

set pc , endcmd

: cmdcolor ; Set colour command

set push , a

set push , z

set a , cmdcolor_str

jsr printstring

jsr gets

set a , [ inputbuf ]

jsr str2int

set a , z

jsr setcolor

jsr reset

set z , pop

set a , pop

set pc , endcmd

: cmdcolor_str dat "Set new color mode:

" , 0

: cmdrandom ; Produces a random number

set push , a

set push , z

; print message

set a , cmdrandom_str

jsr printstring

; get rand, mod number by 10 and make an ascii char

set i , 4

jsr rand

set a , z

jsr printint

; print new line

set a , 0x0A

jsr printchar

; return

set z , pop

set a , pop

set pc , endcmd

: cmdrandom_str dat "A random number: " , 0

: cmdrps ; Rock paper scissors

set push , a

set push , b

set push , c

set push , x

set push , z

: cmdrps_loop

; Cls and Print question string

set a , cmdrps_message

jsr printstring

; Get user's answer

jsr gets

set c , 4

: cmdrps_handleinput

set a , [ inputbuf ]

; Rock?

set b , cmdrps_rock

jsr strcmp

ife z , 0

set pc , cmdrps_choserock

; Paper?

set b , cmdrps_paper

jsr strcmp

ife z , 0

set pc , cmdrps_chosepaper

; Scissors?

set b , cmdrps_scissors

jsr strcmp

ife z , 0

set pc , cmdrps_chosescissors

; Quit?

set b , cmdrps_quit

jsr strcmp

ife z , 0

set pc , cmdrps_end

; Defaults to invalid answer

set pc , cmdrps_invalidanswer

; Jump results

: cmdrps_choserock

set c , 0

set pc , cmdrps_continue

: cmdrps_chosepaper

set c , 1

set pc , cmdrps_continue

: cmdrps_chosescissors

set c , 2

set pc , cmdrps_continue

: cmdrps_continue

; Display CPU's answer

set a , cmdrps_cpuans

jsr printstring

jsr rand

mod z , 3

ife z , 0

set a , cmdrps_rock

ife z , 1

set a , cmdrps_paper

ife z , 2

set a , cmdrps_scissors

jsr printstring

set a , 0x0A

jsr printchar

; Display results

ife z , c

set pc , cmdrps_ondraw

add c , 1

mod c , 3

ifn c , z

set a , cmdrps_youwin

ife c , z

set a , cmdrps_youlose

jsr printstring

; Loop

set pc , cmdrps_loop

: cmdrps_ondraw

set a , cmdrps_draw

jsr printstring

set pc , cmdrps_loop

; Clean up and end

: cmdrps_end

set a , cmdrps_goodbye

jsr printstring

set z , pop

set x , pop

set c , pop

set b , pop

set a , pop

set pc , endcmd

: cmdrps_invalidanswer

set a , cmdrps_invalid

jsr printstring

set pc , cmdrps_loop

; String data

: cmdrps_rock dat "rock" , 0

: cmdrps_paper dat "paper" , 0

: cmdrps_scissors dat "scissors" , 0

: cmdrps_quit dat "quit" , 0

: cmdrps_message dat "Rock, paper or scissors?

(type 'quit' to quit!)

" , 0

: cmdrps_invalid dat "You entered an invalid answer!

Try again:

" , 0

: cmdrps_cpuans dat "Cpu's choice: " , 0

: cmdrps_goodbye dat "Goodbye!

" , 0

: cmdrps_youwin dat "You win!

" , 0

: cmdrps_youlose dat "You lose.

" , 0

: cmdrps_draw dat "The game was a draw.

" , 0

: cmderror ; Unknown command error

set push , a

set a , 0x22

jsr printchar

set a , 0x81C0

jsr printstring

set a , 0x22

jsr printchar

set a , cmdstrError

jsr printstring

set a , pop

set pc , endcmd

: maincmdloop ; Main command prompt loop

set push , a

set push , b

set push , z

jsr gets

set a , [ inputbuf ]

; Check test command

set b , cmdstrtest

jsr strcmp

ife z , 0

set pc , cmdtest

; Check help command

set b , cmdstrhelp

jsr strcmp

ife z , 0

set pc , cmdhelp

; Check cls command

set b , cmdstrcls

jsr strcmp

ife z , 0

set pc , cmdcls

; Check color command

set b , cmdstrcolor

jsr strcmp

ife z , 0

set pc , cmdcolor

; Check rand command

set b , cmdstrrandom

jsr strcmp

ife z , 0

set pc , cmdrandom

; Check rps command

set b , cmdstrrps

jsr strcmp

ife z , 0

set pc , cmdrps

; Default to error

set pc , cmderror

: endcmd ; Called at the end of all commands

set z , pop

set b , pop

set a , pop

set pc , maincmdloop

; STRING

; SUBROUTINES

: strcmp ; Compares 8bit strings in a and b, returns as z

set push , a

set push , b

set push , x

set push , y

: strcmp_loop

set x , [ a ]

set y , [ b ]

add a , 1

add b , 1

and x , 0xFF ; Make this an 8bit comparison

and y , 0xFF ; ^

ifn x , y

set pc , strcmp_diff

ife x , 0

set pc , strcmp_equal

set pc , strcmp_loop

: strcmp_exit

set y , pop

set x , pop

set b , pop

set a , pop

set pc , pop

: strcmp_equal

set z , 0

set pc , strcmp_exit

: strcmp_diff

set z , 1

set pc , strcmp_exit

: str2int ; Converts 8bit string on register a to int on register z

set push , a

set push , b

set z , 0

: str2int_loop

set b , [ a ]

and b , 0xFF ; Mask to 8 bit

; Check for end of string

ife b , 0

set pc , str2int_end

; Convert char to decimal

sub b , 0x30

mul z , 10

add z , b

; Break out if it wasn't a digit

ifg b , 9

set pc , str2int_end

add a , 1

set pc , str2int_loop

: str2int_end

set a , pop

set b , pop

set pc , pop

; CONSOLE

; DATA

: caretpos dat 0

: textcolor dat 0xF000

: inputbuf dat 0x81C0

; SUBROUTINES

: gets ; Get input command line string (stored at inputbuf)

set push , a

set [ 0x9000 ] , 0

: gets_loop

set a , [ 0x9000 ]

; Handle backspace

ife a , 0x08

set pc , gets_backspace

; Handle no input

ife a , 0

set pc , gets_loop

; Draw input to screen

jsr printchar

; Handle linefeed (end input loop)

ife a , 0x0A

set pc , gets_end

: gets_loop_end

set [ 0x9000 ] , 0

set pc , gets_loop

: gets_backspace

jsr backspace

set pc , gets_loop_end

: gets_end

set a , pop

set pc , pop

: backspace ; Handles backspace

ife [ caretpos ] , 0

set pc , pop

set push , a

sub [ caretpos ] , 1

set a , 0x81E0

add a , [ caretpos ]

set [ a ] , [ textcolor ]

set a , pop

set pc , pop

: printchar ; Print character in register a to console

set push , a

set push , b

set push , x

and a , 0xFF

ife a , 0x0A

set pc , printchar_handlelf

set x , 0x81E0

set b , a

add x , [ caretpos ]

add b , [ textcolor ]

set [ x ] , b

add [ caretpos ] , 1

ife [ caretpos ] , 0x20

jsr newline

: printchar_exit

set x , pop

set b , pop

set a , pop

set pc , pop

: printchar_handlelf

jsr newline

set pc , printchar_exit

: printstring ; Print string in register a to console

set push , a

set push , x

set x , a

set a , [ x ]

: printstr_loop

jsr printchar

add x , 1

set a , [ x ]

and a , 0xFF

ifn a , 0

set pc , printstr_loop

set x , pop

set a , pop

set pc , pop

: printint ; Prints integer in register a to console

set push , a

set push , x

set push , y

set x , a

ifg a , 9

set y , 10

ifg a , 99

set y , 100

ifg a , 999

set y , 1000

ifg a , 9999

set y , 10000

: printint_loop

set a , x

div a , y

mod a , 10

add a , 0x30

jsr printchar

ife y , 1

set pc , printint_end

div y , 10

set pc , printint_loop

: printint_end

set y , pop

set x , pop

set a , pop

set pc , pop

: newline ; Jumps to a new line

set push , a

set push , b

set [ caretpos ] , 0

set a , 0x8000

set b , 0x8020

: newline_loop ; Shift console

set [ a ] , [ b ]

add a , 1

add b , 1

ifn b , 0x8200

set pc , newline_loop

set a , 0x81E0

: newline_loopb ; Clear line

set [ a ] , [ textcolor ]

add a , 1

ifn a , 0x8200

set pc , newline_loopb

set b , pop

set a , pop

set pc , pop

: cls ; Clear the screen

set push , a

set a , 0x8000

: cls_loop

set [ a ] , [ textcolor ]

add a , 1

ifn a , 0x8200

set pc , cls_loop

set a , pop

set pc , pop

: setcolor ; Set text color from a register, 8bit

set push , a

shl a , 8

set [ textcolor ] , a

set a , pop

set pc , pop

: reset ; Cls and Reset caret

jsr cls

set [ caretpos ] , 0