Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
1388 lines (1074 sloc) 27.9 KB
;===============================================================
; 0x64c.dasm16
; v0.22
; Author: Pseudox/trevs231
; https://github.com/trevs231/0x10c-Files
;===============================================================
;Jump to program
SET PC, main_inits
;===============================================================
;Global Static Variables and Data
;===============================================================
:SCRN_START DAT 0x8000 ; pointer to first screen location
:SCRN_END DAT 0x81FF ; pointer to last screen location
:KBRD_BUFFER DAT 0x9000 ; pointer to where inputs are read from keyboard
:HEAPARR DAT 0x9100 ; that starting pointer for the heap for malloc
:HEAP DAT 0x9200 ; start of the stack of memory addresses
;==============================================================
:SYS_START_MSG ;logo at startup
DAT " ___ ___ _ _ "
DAT " / \\ / __|| || | "
DAT " | | | |_ _| |__ | || |_ ___ "
DAT " | | | \\ \\/ / _ \\|__ _/ __| "
DAT " | |_| |> <| |_| | | || (__ "
DAT " \\___//_/\\_\\\\___/ |_| \\___| "
DAT " THE FOUNDATION OF AN OPERATING "
DAT " SYSTEM FOR THE DCPU-16 "
DAT " by Pseudox/trevs231 v0.2 ", 0
:COMMAND_INIT_MSG
DAT " Type 'help' for a list of "
DAT " commands 64k RAM k FREE ", 0
;===============================================================
;Program start/Initializations
;===============================================================
:main_inits
SET [COLOUR], 0xF000 ;white on black
SET C, [KBRD_BUFFER];clearing keyboard buffer
SET [c], 0
SET C, 0
SET j, 0
SET i, 0xFFFF
:init_RAM_check_loop ;checking free RAM
IFE [i], 0
ADD j, 1
SUB i, 1
IFN i, 0
SET PC, init_RAM_check_loop
DIV j, 1000
SET A, j
MOD j, 10 ;ones
DIV A, 10 ;tens
ADD j, 0x30
ADD A, 0x30
JSR clrscrn ;clearing screen
SET B, SYS_START_MSG
JSR printDAT ; shows logo
SET [SLEEP_DURATION], 0xA000
JSR sleep
JSR sleep
JSR clrscrn ;clearing screen
SET B, COMMAND_INIT_MSG
JSR printDAT ;Command instructions
SUB [SCRN_LCN], 9 ;printing available RAM on screen
SET [SCRN_CHAR], A
JSR printChar
SET [SCRN_CHAR], j
JSR printChar
ADD [SCRN_LCN], 7
;=============================================================
;Main loop
;=============================================================
:main
JSR COMMAND_LINE
SET PC, main ;repeat main
:EXIT
SET J, 0x40
:crash
SET PC, crash
; end of main section
;===============================================================
;Subroutines
;================================================================
;==============================================================
;Command Line Subroutines
;==============================================================
;command line prompts. Text is the command to be typed
; Number is the mode
:EXIT_COMMAND DAT "exit", 0, 1 ;must be first
:HELP_COMMAND DAT "help", 0, 2
:MINECRAFT_COMMAND DAT "minecraft", 0, 3, 0 ;must end in 0
;compares input to commands and executes command
:COMMAND_LINE
SET PUSH, A
SET PUSH, B
SET PUSH, i
JSR getLine
IFE [LINE_BUFFER], 0 ; nothign in buffer
SET PC, COMMAND_LINE_DONE
;go through commands
SET B, EXIT_COMMAND
JSR COMMAND_LINE_COMPARE
SET B, HELP_COMMAND
JSR COMMAND_LINE_COMPARE
SET B, MINECRAFT_COMMAND
JSR COMMAND_LINE_COMPARE
SET A, 0 ; invalid command
:COMMAND_LINE_RUN ;jumps to selected command
MUL A, 4
ADD PC, A
JSR CMD_ERROR_SR
SET PC, COMMAND_LINE_DONE
JSR EXIT_COMMAND_SR
SET PC, COMMAND_LINE_DONE
JSR HELP_COMMAND_SR
SET PC, COMMAND_LINE_DONE
JSR MINECRAFT_COMMAND_SR
:COMMAND_LINE_DONE
SET i, POP
SET B, POP
SET A, POP
SET PC, POP
;compares command at B with buffer
;returns to COMMAND_CHECK list if false
;returns to
:COMMAND_LINE_COMPARE
SET i, 0
:COMMAND_LINE_COMPARE_LOOP
IFE [LINE_BUFFER+i], 0 ;end of buffer?
SET PC, COMMAND_LINE_COMPARE_DONE
IFE [B], 0 ;end of CMD?
SET PC, COMMAND_LINE_COMPARE_FALSE
IFN [LINE_BUFFER+i], [B]
SET PC, COMMAND_LINE_COMPARE_FALSE
ADD i, 1
ADD B, 1
SET PC, COMMAND_LINE_COMPARE_LOOP
:COMMAND_LINE_COMPARE_FALSE
SET PC, POP
:COMMAND_LINE_COMPARE_DONE
ADD B, 1
SET A, [B] ;sets A to mode
IFE i, 0
SET A, 0
SET POP, 0 ;gets rid of old place, garbage
SET PC, COMMAND_LINE_RUN
;======================================================
;Commands
;prints an error
:CMD_ERROR_MSG DAT "command not recognized", 0
:CMD_ERROR_SR
SET PUSH, B
JSR newLine
SET B, CMD_ERROR_MSG
JSR printDAT
SET B, POP
SET PC, POP
;=====================================================
;exits the Command program
:EXIT_COMMAND_MSG DAT "exiting...", 0
:EXIT_COMMAND_SR
SET PUSH, B
JSR newLine
SET B, EXIT_COMMAND_MSG
JSR printDAT
SET B, POP
SET POP, 0
SET i, POP
SET B, POP
SET A, POP
SET POP, 0
SET PC, EXIT
;=====================================================
;prints commands that can be used
:HELP_COMMAND_MSG DAT "available commands:", 0
:HELP_COMMAND_SR
SET PUSH, B
JSR newLine
SET B, HELP_COMMAND_MSG
JSR printDAT
SET B, EXIT_COMMAND
:HELP_COMMAND_loop
JSR newLine
JSR printDAT
ADD B, 2
IFN [B], 0
SET PC, HELP_COMMAND_loop
SET B, POP
SET PC, POP
;=====================================================
;begins the MINECRAFT GAME
:MINECRAFT_START_SCREEN
DAT " MINECRAFT for DCPU-16 v1.5 "
DAT " by Pseudox/trevs231", 0
:MINECRAFT_INSTRUCTIONS1
DAT " p - Quit o - Restart "
DAT " w,a,s,d - Place/ remove blocks "
DAT " arrow keys - Move", 0
:MINECRAFT_INSTRUCTIONS2
DAT " e - Change block", 0
:MINECRAFT_COMMAND_SR
JSR clrSCRN
SET [SCRN_LCN], 0x8080 ;print title screen
SET B, MINECRAFT_START_SCREEN
JSR printDAT
JSR newLine
SET B, MINECRAFT_INSTRUCTIONS1
JSR printDAT
JSR newLine
SET B, MINECRAFT_INSTRUCTIONS2
JSR printDAT
SET [SLEEP_DURATION], 0xF000
JSR sleep
JSR sleep
JSR MINECRAFT_init ;play minecraft! :D
JSR clrSCRN
SET PC, POP
;==============================================================
;Screen Subroutines
;=============================================================
; known format: in video ram:
; (4 Letter bits)(4 background bits)
; (1 flashing)(7 ascii bits):
; (HRGB HRGB)|(ASCII)
:COLOUR RESERVE 1 ; 0x(HRGB HRGB)(8 or 0)0
:SCRN_LCN RESERVE 1 ;0x8000 - 0x81FF
:SCRN_CHAR RESERVE 1 ;some ASCII value
;==========================================================
;Prints number in A in decimal
:printNum
SET PUSH, i
SET PUSH, j
SET PUSH, x
SET PUSH, y
SET PUSH, O
SET j, 0
SET y, 10000
SET i, A
:printNum_loop
DIV i, y
SET x, i ;saving already printed
MUL x, y
ADD j, x
ADD i, 0x30
SET [SCRN_CHAR], i
JSR printChar
SET i, A
SUB i, j
DIV y, 10
IFN y, 0
SET PC, printNum_loop
SET O, POP
SET y, POP
SET x, POP
SET j, POP
SET i, POP
SET PC, POP
;=======================================================
;prints string at the location pointed to by B
; string must be followed by a 0
:printDAT
:printDAT_loop ;prints each char until 0
IFE [B], 0
SET PC, printDAT_done
SET [SCRN_CHAR], [B]
JSR printChar
ADD B, 1
SET PC, printDAT_loop
:printDAT_done
SET PC, POP
;========================================================
;takes values in COLOUR, and writes character
;in SCRN_CHAR to the location SCRN_LCN
;COLOUR should be 0xzz00 for regular
; and 0xzz80 for flashing
;increments screen index after
:printChar
SET PUSH, A
SET PUSH, B
SET PUSH, O
;checking validity of location
IFG [SCRN_START], [SCRN_LCN]
SET PC, printChar_smallLCN
IFG [SCRN_LCN], [SCRN_END]
SET PC, printChar_bigLCN
SET PC, printChar_okLCN
:printChar_smallLCN
JSR clrSCRN
SET PC, printChar_okLCN
:printChar_bigLCN
JSR newLine
:printChar_okLCN
;setting values into one location
SET A, [SCRN_LCN]
SET B, [COLOUR]
BOR B, [SCRN_CHAR]
;printing value
SET [A], B
;increment location
ADD [SCRN_LCN], 1
SET O, POP
SET B, POP
SET A, POP
SET PC, POP
;Sets LCRN_LCN to the next line
;If on the last line, pushes all lines up one
; then clears the bottom
:newLine
SET PUSH, A
SET A, [SCRN_LCN]
MOD A, 32 ;column
SUB [SCRN_LCN], A
ADD [SCRN_LCN], 32 ;now at beginning of NL
SET A, 2 ;in case of screen shift
IFG [SCRN_LCN], [SCRN_END]
SET PC, newLine_off
:newLine_end
SET A, POP
SET PC, POP
:newLine_off
SET A, 2 ;shift up by 2
JSR shiftSCRN
SET A, [SCRN_END]
SUB A, 0x3F
SET [SCRN_LCN], A
SET PC, newLine_end
;Takes value in A and shifts the screen up
; by that many lines
; Also performs a newline operation on the adjusted screen.
:shiftSCRN
SET PUSH, i
SET PUSH, j
SET PUSH, z
IFE A, 0;do nothing if A=0
SET PC, shiftSCRN_done
IFG A, 16
SET PC, clrSCRN ;will clear screen if A too big
SET j, [SCRN_START] ;location to copy
SET z, j
SET i, 32
MUL i, A
ADD j, i ;location to rewrite
:shiftSCRN_loop ;rewrite chars
IFG j, [SCRN_END]
SET PC, shiftSCRN_clear
SET [Z], [j]
ADD z, 1
ADD j, 1
SET PC, shiftSCRN_loop
:shiftSCRN_clear ;clear the rest of the screen
SET [z], [COLOUR]
ADD z, 1
IFG z, [SCRN_END]
SET PC, shiftSCRN_done
SET PC, shiftSCRN_clear
SET i, [SCRN_LCN]
MOD i, 32 ;column
SUB [SCRN_LCN], i
SUB A, 1
MUL A, 32
SUB [SCRN_LCN], A
:shiftSCRN_done
SET z, POP
SET j, POP
SET i, POP
SET PC, POP
;Clears screen background.
;uses background color in COLOUR
;resets SCRN_LCN to the first location
:clrSCRN
SET PUSH, A
SET PUSH, i
;setting iteration
SET i, [SCRN_START]
SET A, [COLOUR]
:clrSCRN_loop
SET [i], A
ADD i, 1
IFN i, [SCRN_END]
SET PC, clrSCRN_loop
SET [i], A
SET [SCRN_LCN], [SCRN_START]
SET i, POP
SET A, POP
SET PC, POP
;KEYBOARD SUBROUTINES--------------------------------
:LINE_BUFFER RESERVE 31 ;30 values, and a required 0 at end
;Gets one line of info from keyboard, finished after ENTER
;Returns ASCII values in LINE_BUFFER
;Also if the value entered only contains numbers
; the first 4 will be taken (so max 9999 )
; and their value will be saved in A
:getLine
SET PUSH, i
SET PUSH, j
SET PUSH, B
JSR newLine
SET j, 0 ;number of entries
SET i, [SCRN_LCN]
ADD i, 0x1F ;limit to how much can be typed
SET [SCRN_CHAR], 62 ;>
JSR printChar
:getLine_loop
IFE [SCRN_LCN], i ;checking if line is full
SET PC, getLine_lineFull
JSR key_CharIn
IFE B, 10 ;if it is ENTER/nl
SET PC, getLine_ENTER
SET PC, getLine_loop
:getLine_lineFull
SUB [SCRN_LCN], 1
SET [SCRN_CHAR], 32 ; erase last entry
JSR printChar
SUB [SCRN_LCN], 1
SET PC, getLine_loop
:getLine_ENTER
SUB [SCRN_LCN], 2
SET j, [SCRN_LCN]
MOD j, 32 ;how many items
SET B, j ;for math computation later
SET i, [SCRN_LCN]
SET [LINE_BUFFER+j], 0 ;end of line
:getLine_ENTERloop
IFE j, 0
SET PC, getLine_math
SUB j, 1
SET [LINE_BUFFER+j], [i] ;iterating, copying values
AND [LINE_BUFFER+j], 0xFF
IFG [LINE_BUFFER+j], 0x39 ; no math if letters
SET B, 0
IFG 0x30, [LINE_BUFFER+j]
SET B, 0
SUB i, 1
SET PC, getLine_ENTERloop
:getLine_math ;for computing the number to save in A
SET A, 0
SET i, 1 ;multiplication factor
IFG B, 4
SET B, 4
:getLine_mathLoop
IFE B, 0
SET PC, getLine_done
SUB B, 1
SET j, [LINE_BUFFER+B]
SUB j, 0x30
MUL j, i
MUL i, 10
ADD A, j
SET PC, getLine_mathLoop
:getLine_done
SET B, POP
SET j, POP
SET i, POP
SET PC, POP
;used for taking ASCII values from keyboard
;prints the value on screen stores value in B
;8 for bs 10 for nl
:key_CharIn
SET PUSH, C
SET C, [KBRD_BUFFER] ;where input will appear
SET [SCRN_CHAR], 95 ;show cursor
JSR printChar
SUB [SCRN_LCN], 1
:key_CharIn_loop
SET B, [C]
IFE B, 0 ;no value in buffer
SET PC, key_CharIn_loop
SET [C], 0
IFE B, 8 ;backspace
SET PC, key_CharIn_bs
SET [SCRN_CHAR], B
JSR printChar
SET C, POP
SET PC, POP
:key_CharIn_bs
SET B, [SCRN_LCN] ;check if first location
MOD B, 0x20
IFE B, 1
SET PC, key_CharIn_loop
SET [SCRN_CHAR], 32 ; erase cursor
JSR printChar
SUB [SCRN_LCN], 2
SET [SCRN_CHAR], 95 ;show cursor
JSR printChar
SUB [SCRN_LCN], 1
SET PC, key_CharIn_loop
;===============================================================
;MEMORY ALLOCATION SUBROUTINES
;===============================================================
; https://github.com/ryban/DCPPU16
; Author: Ryban
; Returns pointers to 64 word chunks
; maintain a 256 word list of empty 64 word chunks
; when you need a new one you loop through the 256 word list until you find an empty one
; Multiply the index of that marker (from the 256 word array) by 64 to get the address
; the value returned in A is a pointer to the start of the memory
:malloc
SET PUSH, B
SET PUSH, C
SET A, 0
SET B, [HEAPARR]
:maloc_l4
SET C, [B]
IFE C, 0
SET PC, maloc_found
IFG A, 0xff ; A > 255
SET PC, maloc_full
ADD A, 1
ADD B, 1
SET PC, maloc_l4
:maloc_found
; ADD B, A
SET [B], 0xffff ; mark chunk taken
MUL A, 0x40 ; A * 64
SET B, [HEAP]
ADD A, B
SET C, POP
SET B, POP
SET PC, POP
:maloc_full
SET A, 0x2000 ; A hopefully harmless area...
SET C, POP
SET B, POP
SET PC, POP
;=================================================================
; Author: Ryban
; releases memory given by malloc.
; This IS NOT automatically done, be sure to free memory when you are done
; A is the pointer to your memory chunk to be freed
:free
SET PUSH, B
SET B, [HEAP]
SUB A, B
DIV A, 64
SET B, [HEAPARR]
ADD A, B
SET [A], 0
SET B, POP
SET PC, POP
;==================================================================
;===================================================================
;Math
;==================================================================
:MATH1 RESERVE 2
:MATH2 RESERVE 2
:MUL_ANS RESERVE 4
;==================================================================
;32bit addition
;performs MATH1+MATH2
;Result stored in MATH1
; O is set to 0x1 if overflow. 0x0 otherwise
:ADD32
SET PUSH, X
SET PUSH, I
SET I, 1
ADD [MATH1+I], [MATH2+I] ;adding lower words
ADD [MATH1], O ;carry?
SET X, O ;carry?
ADD [MATH1], [MATH2] ;adding upper words
ADD O, X ;carry?
SET I, POP
SET X, POP
SET PC, POP
;==============================================================
;32 bit subtraction
;performs MATH1-MATH2
;Result stored in MATH1
; O set to 0xFFFF for underflow, 0x0 otherwise
:SUB32
SET PUSH, X
SET PUSH, I
SET I, 1
SUB [MATH1+I], [MATH2+I] ;sub lower words
SUB [MATH2], O ;borrow?
SET X, O ;borrow?
SUB [MATH1], [MATH2] ;sub upper words
SUB O, X ;borrow?
SUB O, 1 ;borrow?
SET I, POP
SET X, POP
SET PC, POP
;==============================================================
;32 bit multiplication
;performs MATH1*MATH2
;stores result in MUL_ANS
:MUL32
SET PUSH, I
SET PUSH, J
SET I, 1
SET J, 3
SET PUSH, [MATH1+I]
MUL [MATH1+I], [MATH2+I] ;multiply 1
SET [MUL_ANS+J], [MATH1+I]
SET [MATH1+I], POP
SET J, 2
SET [MUL_ANS+J], O
SET PUSH, [MATH1]
MUL [MATH1], [MATH2+I] ;Multiply 2
SET [MUL_ANS+I], O
ADD [MUL_ANS+J], [MATH1]
SET [MATH1], POP
ADD [MUL_ANS+I], O
SET [MUL_ANS], O
MUL [MATH1+I], [MATH2] ;MULTIPLY 3
ADD [MUL_ANS+I], O
ADD [MUL_ANS], O
ADD [MUL_ANS+J], [MATH1+I]
ADD [MUL_ANS+I], O
ADD [MUL_ANS], O
MUL [MATH1], [MATH2] ;multiply 4
ADD [MUL_ANS], O
ADD [MUL_ANS+I], [MATH1]
ADD [MUL_ANS], O
SET J, POP
SET I, POP
SET PC, POP
;====================================================================
;Misc Subroutines
;===================================================================
;sleeps system. takes SLEEP_DURATION as a parameter
:SLEEP_DURATION RESERVE 1
:sleep
SET PUSH, I
SET I, 0
:sleep_loop
ADD I, 1
IFG I, [SLEEP_DURATION]
SET PC, sleep_done
SET PC, sleep_loop
:sleep_done
SET i, POP
SET PC, POP
;=============================================================
;Games
;=============================================================
;============================================================
;MINECRAFT GAME FOR DCPU-16 v1.5 by Pseudox/trevs231
;============================================================
;A= used in maloc and free
;B= prevents other buttons from messing up input
;C= falling counter
;X= helper
;Y= water flow timer?
;Z= input buffer
;I= helper
;J= helper
;====================================================
;Variables and constants
:MC_PLAYER_POS RESERVE 1
:MC_CURRENT_BLOCK RESERVE 1
:MC_SKY_CHAR DAT 0x0B00
:MC_WATER_CHAR DAT 0x0100
:MC_BLOCK_CHARS DAT 0x182A, 0x862A, 0x0200, 0x0800, 0x0600
DAT 0x782A, 0xE82A, 0xC82A, 0xB82A, 0
; water source, dirt, grass, rock, cobblestone, wood, gold deposit
; redstone, diamond,
:MC_PLAYER_CHAR DAT 0x4058
:MC_FALL_TIME DAT 0x0500
:MC_up_key DAT 0x0003 ;up arrow
:MC_left_key DAT 0x0001 ;left arrow
:MC_right_key DAT 0x0002 ;right arrow
:MC_do_up_key DAT 0x0077 ;w
:MC_do_down_key DAT 0x0073 ;s
:MC_do_left_key DAT 0x0061 ;a
:MC_do_right_key DAT 0x0064 ;d
:MC_swap_key DAT 0x0065 ;e
:MC_reset_key DAT 0x006F ;o
:MC_quit_key DAT 0x0070 ;p
;=====================================================
:MINECRAFT_init
SET PUSH, B
SET PUSH, C
SET PUSH, X
SET PUSH, Y
SET PUSH, Z
SET PUSH, I
SET PUSH, J
:MC_reset_point
SET z, [KBRD_BUFFER] ;initialize input buffer
SET [z], 0
SET x, [SCRN_START]
SET C, [MC_FALL_TIME] ;for fall speed
SET Y, [MC_FALL_TIME] ;for water flow speed
SET J, x
ADD j, 0x100
:MINECRAFT_init_loop1
SET [x], [MC_SKY_CHAR]
ADD x, 1
IFG j, x
SET PC, MINECRAFT_init_loop1
ADD j, 0x20
SET i, 2
:MINECRAFT_init_loop2
SET [x], [MC_BLOCK_CHARS+i]
ADD x, 1
IFG j, x
SET PC, MINECRAFT_init_loop2
ADD j, 0x40
SET i, 1
:MINECRAFT_init_loop3
SET [x], [MC_BLOCK_CHARS+i]
ADD x, 1
IFG j, x
SET PC, MINECRAFT_init_loop3
SET j, [SCRN_END]
ADD j, 0x1
SET i, 3
:MINECRAFT_init_loop4
SET [x], [MC_BLOCK_CHARS+i]
ADD x, 1
IFG j, x
SET PC, MINECRAFT_init_loop4
SET i, 1
SET [MC_CURRENT_BLOCK], [MC_BLOCK_CHARS+i] ;show current block
SET x, [SCRN_START]
SET [x], [MC_CURRENT_BLOCK]
;initialize player
SET [MC_PLAYER_POS], [SCRN_START]
ADD [MC_PLAYER_POS], 0xF0
JSR MC_print_player
SET B, 0x100
;===========================================================
:MC_game_loop
JSR MC_in_air_check
JSR MC_water_flow
IFE [z], [MC_up_key]
JSR MC_jump
IFE [z], [MC_left_key]
JSR MC_move_left
IFE [z], [MC_right_key]
JSR MC_move_right
IFE [z], [MC_do_up_key]
JSR MC_do_up
IFE [z], [MC_do_down_key]
JSR MC_do_down
IFE [z], [MC_do_left_key]
JSR MC_do_left
IFE [z], [MC_do_right_key]
JSR MC_do_right
IFE [z], [MC_swap_key]
JSR MC_swap_item
IFE [z], [MC_reset_key]
SET PC, MC_reset_game
IFE [z], [MC_quit_key]
SET PC, MC_game_exit
SUB B, 1
IFE B, 0
JSR MC_reset_input
SET PC, MC_game_loop
;===================================================
:MC_game_exit
SET [z], 0
SET J, POP
SET I, POP
SET Z, POP
SET Y, POP
SET X, POP
SET C, POP
SET B, POP
SET PC, POP
;=====================================================
;prevents input buffer from getting full
;while preventing issues with input
:MC_reset_input
SET [z], 0
SET B, 0x100
SET PC, POP
;=====================================================
:MC_jump
SET [z], 0
:MC_jump_water
SET J, [MC_PLAYER_POS]
SET X, [MC_PLAYER_POS]
SUB J, 0x20
IFG [SCRN_START], j ;at the top?
SET PC, POP
IFE [j], [MC_WATER_CHAR]
SET PC, MC_jump2
IFN [j], [MC_SKY_CHAR] ;block above?
SET PC, POP
IFG [MC_FALL_TIME], C ;can't if in the air
SET PC, POP
:MC_jump2
AND [X], 0x0F00
SET [MC_PLAYER_POS], j
JSR MC_print_player
SUB C, 1
SET PC, POP
;=====================================================
:MC_move_left
SET [z], 0
SET j, [MC_PLAYER_POS]
SET x, [MC_PLAYER_POS]
MOD j, 0x20
IFE j, 0
SET PC, MC_wrap_left ;at left edge?
SET J, [MC_PLAYER_POS]
SUB j, 1
IFE [j], [MC_SKY_CHAR] ;block above?
SET PC, MC_move_left2
IFN [j], [MC_WATER_CHAR]
SET PC, POP
:MC_move_left2
AND [X], 0x0F00
SET [MC_PLAYER_POS], j
JSR MC_print_player
SET PC, POP
:MC_wrap_left
SET J, [MC_PLAYER_POS]
ADD J, 0x1F
IFE [j], [MC_SKY_CHAR] ;block above?
SET PC, MC_move_leftw2
IFN [j], [MC_WATER_CHAR]
SET PC, POP
:MC_move_leftw2
AND [X], 0x0F00
SET [MC_PLAYER_POS], j
JSR MC_print_player
SET PC, POP
;====================================================
:MC_move_right
SET [z], 0
SET x, [MC_PLAYER_POS]
SET j, [MC_PLAYER_POS]
MOD j, 0x20
IFE j, 0x1F ;at right edge?
SET PC, MC_wrap_right
SET J, [MC_PLAYER_POS]
ADD j, 1
IFE [j], [MC_SKY_CHAR] ;block above?
SET PC, MC_move_right2
IFN [j], [MC_WATER_CHAR]
SET PC, POP
:MC_move_right2
AND [X], 0x0F00
SET [MC_PLAYER_POS], j
JSR MC_print_player
SET PC, POP
:MC_wrap_right
SET J, [MC_PLAYER_POS]
SUB J, 0x1F
IFE [j], [MC_SKY_CHAR] ;block above?
SET PC, MC_move_rightw2
IFN [j], [MC_WATER_CHAR]
SET PC, POP
:MC_move_rightw2
AND [X], 0x0F00
SET [MC_PLAYER_POS], j
JSR MC_print_player
SET PC, POP
;======================================================
:MC_do_up
SET [z], 0
SET J, [MC_PLAYER_POS]
SUB J, 0x20
IFG [SCRN_START], j ;at the top?
SET PC, POP
IFE [SCRN_START], j ;current block?
SET PC, POP
IFN [j], [MC_SKY_CHAR] ;is it a block?
SET PC, MC_do_is_block
SET [j], [MC_CURRENT_BLOCK]
SET PC, POP
;======================================================
:MC_do_down
SET [z], 0
SET J, [MC_PLAYER_POS]
ADD J, 0x20
IFG J, [SCRN_END] ;at the bottom?
SET PC, POP
IFN [j], [MC_SKY_CHAR] ;is it a block?
SET PC, MC_do_is_block
SET [j], [MC_CURRENT_BLOCK]
SET PC, POP
;======================================================
:MC_do_left
SET [z], 0
SET j, [MC_PLAYER_POS]
MOD j, 0x20
IFE j, 0x0 ;at left edge?
SET PC, MC_do_wrap_left
SET J, [MC_PLAYER_POS]
SUB j, 1
IFE j, [SCRN_START] ;current block?
SET PC, POP
IFN [j], [MC_SKY_CHAR] ;block there?
SET PC, MC_do_is_block
SET [j], [MC_CURRENT_BLOCK]
SET PC, POP
:MC_do_wrap_left
SET J, [MC_PLAYER_POS]
ADD J, 0x1F
IFN [J], [MC_SKY_CHAR] ;block there?
SET PC, MC_do_is_block
SET [j], [MC_CURRENT_BLOCK]
SET PC, POP
;======================================================
:MC_do_right
SET [z], 0
SET j, [MC_PLAYER_POS]
MOD j, 0x20
IFE j, 0x1F ;at right edge?
SET PC, MC_do_wrap_right
SET J, [MC_PLAYER_POS]
ADD j, 1
IFN [j], [MC_SKY_CHAR] ;block there?
SET PC, MC_do_is_block
SET [j], [MC_CURRENT_BLOCK]
SET PC, POP
:MC_do_wrap_right
SET J, [MC_PLAYER_POS]
SUB J, 0x1F
IFE j, [SCRN_START] ;current block?
SET PC, POP
IFN [J], [MC_SKY_CHAR] ;block there?
SET PC, MC_do_is_block
SET [j], [MC_CURRENT_BLOCK]
SET PC, POP
;======================================================
:MC_do_is_block
SET [j], [MC_SKY_CHAR]
SET PC, POP
;======================================================
:MC_swap_item
SET [z], 0
SET j, MC_BLOCK_CHARS
:MC_swap_item_loop
IFE [MC_CURRENT_BLOCK], [j]
SET PC, MC_swap_item_x
ADD j, 1
SET PC, MC_swap_item_loop
:MC_swap_item_x
ADD j, 1
IFE [j], 0
SET PC, MC_swap_item_reset
SET [MC_CURRENT_BLOCK], [j]
SET x, [SCRN_START]
SET [x], [MC_CURRENT_BLOCK]
SET PC, POP
:MC_swap_item_reset
SET [MC_CURRENT_BLOCK], [MC_BLOCK_CHARS]
SET x, [SCRN_START]
SET [x], [MC_CURRENT_BLOCK]
SET PC, POP
;======================================================
:MC_reset_game
SET [z], 0
SET PC, MC_reset_point
;======================================================
;checks if player is in the air
:MC_in_air_check
SET X, [MC_PLAYER_POS]
ADD X, 0x20
IFG x, [SCRN_END] ;at bottom?
SET PC, POP
IFE [x], [MC_SKY_CHAR] ;ground below?
SET PC, MC_in_air
IFE [x], [MC_WATER_CHAR]
SET PC, MC_in_air
SET C, [MC_FALL_TIME]
SET PC, pop
:MC_in_air
SUB C, 1
IFN C, 0 ;time up?
SET PC, POP
;dont put anything here
:MC_fall
SET x, [MC_PLAYER_POS]
AND [x], 0x0F00
ADD [MC_PLAYER_POS], 0x20
SET C, [MC_FALL_TIME]
JSR MC_print_player
SET PC, POP
:MC_in_air_check_on_ground
SET C, [MC_FALL_TIME]
SET PC, POP
;======================================================
:MC_print_player
SET X, [MC_PLAYER_POS]
BOR [x], [MC_PLAYER_CHAR]
SET PC, POP
;======================================================
:MC_water_flow
IFE Y, 0
SET PC, MC_water_check
SUB Y, 1 ;only does this every so often
SET PC, POP
:MC_water_check
JSR malloc
SET j, a
SET PUSH, a ;a contains pointer to dynamic mem
SET i, [SCRN_START]
ADD i, 1
:MC_water_check_loop
IFE [i], [MC_BLOCK_CHARS] ;are there any sources or water?
JSR MC_flow
SET a, [i]
AND a, 0x0F00
IFE a, [MC_WATER_CHAR]
JSR MC_flow
ADD i, 1
IFG [SCRN_END], i
SET PC, MC_water_check_loop
SET [j], 0
SET A, POP ;making sure last entry is zero
SET j, a
:MC_water_print_loop
SET i, [j]
IFE i, 0
SET PC, MC_flow_done
AND [i], 0xF0FF
BOR [i], [MC_WATER_CHAR]
ADD j, 1
SET PC, MC_water_print_loop
:MC_flow_done
JSR free
SET Y, [MC_FALL_TIME]
SET PC, POP
:MC_flow_save
SET [j], x ;saves location on screen
ADD j, 1
SET PC, POP
;=====================================================
:MC_flow
SET x, i
ADD x, 0x20
IFG x, [SCRN_END] ;at bottom?
SET PC, MC_flow_left
SET a, [x]
AND a, 0x0F00
IFE a, [MC_SKY_CHAR] ;block below?
JSR MC_flow_save
:MC_flow_left
SET x, i
MOD x, 0x20
IFE x, 0x0 ;at left edge?
SET PC, MC_flow_wrap_left
SET x, i
SUB x, 1
IFE x, [SCRN_START] ;current block?
SET PC, MC_flow_right
SET a, [x]
AND a, 0x0F00
IFE a, [MC_SKY_CHAR] ;block below?
JSR MC_flow_save
SET PC, MC_flow_right
:MC_flow_wrap_left
SET x, i
ADD x, 0x1F
SET a, [x]
AND a, 0x0F00
IFE a, [MC_SKY_CHAR] ;block below?
JSR MC_flow_save
:MC_flow_right
SET x, i
MOD x, 0x20
IFE x, 0x1F ;at right edge?
SET PC, MC_flow_wrap_right
SET x, i
ADD x, 1
SET a, [x]
AND a, 0x0F00
IFE a, [MC_SKY_CHAR] ;block below?
JSR MC_flow_save
SET PC, POP
:MC_flow_wrap_right
SET x, i
SUB x, 0x1F
IFE x, [SCRN_START] ;current block?
SET PC, POP
SET a, [x]
AND a, 0x0F00
IFE a, [MC_SKY_CHAR] ;block below?
JSR MC_flow_save
SET PC, POP
;==============================================================