'Welcome to the Linaxe v1.0 Operating System ' for the Picaxe 28X-1 uC 'Many of the comments below are outdated and no longer apply. 'I'm just bad at updating my documention =( '************************ '* Process variables * '************************ symbols: { symbol a_offset = 0 'variables a-z use offsets 0-25 symbol b_offset = 1 symbol c_offset = 2 symbol d_offset = 3 symbol e_offset = 4 symbol f_offset = 5 symbol g_offset = 6 symbol h_offset = 7 symbol i_offset = 8 symbol j_offset = 9 symbol k_offset = 10 symbol l_offset = 11 symbol m_offset = 12 symbol n_offset = 13 symbol o_offset = 14 symbol p_offset = 15 symbol q_offset = 16 symbol r_offset = 17 symbol s_offset = 18 symbol t_offset = 19 symbol u_offset = 20 symbol v_offset = 21 symbol w_offset = 22 symbol x_offset = 23 symbol y_offset = 24 symbol z_offset = 25 'z ptr is actually 2-bytes (25 and 26) (16 bits) symbol do_stack_ptr_offset = 27 symbol do_stack_offset = 28 'do_stack = 3 2-byte values = 6 bytes (28-33) symbol gosub_stack_ptr_offset = 33 symbol gosub_stack_offset = 35 'gosub_stack = 3 2-byte values = 6 bytes (35-40) symbol proc0_offset = 0 'proc0 = 0-40 symbol proc1_offset = 41 'proc1 = 41-81 symbol proc2_offset = 82 'proc2 = 82-123 '************************ '* Interpreter Variables* '************************ symbol pc0 = w13 symbol pc1 = w12 symbol pc2 = w11 symbol cur_pc = w10 symbol cpc_msb = b21 symbol cpc_lsb = b20 symbol cur_proc = b19 symbol tempb0 = b17 symbol tempb1 = b16 symbol tempb2 = b15 symbol tempb3 = b14 symbol tempb4 = b13 symbol tempb5 = b12 symbol tempb6 = b11 symbol tempb7 = b10 symbol tempw0 = w8 symbol tempw1 = w7 symbol tempw2 = w6 symbol tempw3 = w5 symbol instr = b9 symbol oprnd0 = b8 symbol oprnd1 = b7 symbol oprnd2 = b6 symbol oprnd3 = b5 symbol oprnd4 = b4 symbol oprnd5 = b3 symbol oprnd6 = b2 symbol i2c_address = b18 '************************ '* System Variables * '************************ symbol system_status = b0 'bit0=proc0 active 'bit1=proc1 active 'bit2=proc2 active symbol proc0_active = bit0 symbol proc1_active = bit1 symbol proc2_active = bit2 symbol ROM_A = %10100100 symbol ROM_B = %10101100 symbol ROM_C = %10100000 symbol ROM_D = %10101000 symbol RAM_A = %10100010 symbol RAM_B = %10101110 symbol SLAVE = %11100000 symbol proc_rom = b1 'bit8 & bit9 = proc_0 rom 'bit10 & bit11 = proc_1 rom 'bit12 & bit13 = proc_2 rom 'bit14 & bit15 = unused } 'bytes 124, 125, 126 and 127 of the scratchpad memory are still free 'Do 3 "Virtual Consoles" that can each run their own programs 'it will be wasteful, but if I have each line = 20 bytes (24 byte line, minus 3 for line num + ":"), I can do auto-line numbering, and then 'automatically skip to appropriate locations in memory (i.e. line 10 = 10*20 -> starts at byte 200! taadaa!) 'this also allows me to insert new lines into the editor by just shifting everything by 20 bytes (slow, but, whatever) ' 'line should be stored as "token" + extra extra extra extra, etc. 'use the scratchpad memory for the A-Z variables,stacks,etc -- pointers will make things much easier, as token for var = point location 'Let A=num_1+1; 'let A=Var_A + 1 'FOR(A,1,5,1) ' CODE ' ' '0-25 = variables ' 'CHRIS# 'DO 'WHILE(VAR,start_val,stop_val,step_val) 'ADD(destination_var,type1,val1,type2,val2) 'SUB(type,val,type) 'LOAD(var,location_hi,location_lo) 'IF(VAR,comparison,type,val,jmp_loc_hi,jmp_loc_lo) 'MULT(destination_var,type1,val1,type2,val2) 'DIV(Destination_var,type1,val1,type2,val2) 'DISP(string) 'AND(destination_var,type1,val1,type2,val2) 'OR(destination_var,type1,val1,type2,val2) 'XOR(destination_var,type1,val1,type2,val2) 'ANDNOT(destination_var,type1,val1,type2,val2) 'XNOR(destination_var,type1,val1,type2,val2) 'ORNOT(destination_var,type1,val1,type2,val2) 'GOSUB(MSB,LSB) 'RETURN 'SETPTR(MSB,LSB) '****** FILE LAYOUT ************ 'DISKMAP stored in slot 0, disk A 'Disk A-D 'Slot 0-7 '32 total program slots '32 * 9 = 288 bytes 'byte 9 = file type 'bytes 1-8 = filename '******************************* '************************************************ '* Boot Code * '* * '************************************************ boot: EEPROM $00,("?9?5312C?A864?'?") ' Function keys EEPROM $10,("?????Q1???ZSAW2?") ' Main keyboard keys EEPROM $20,("?CXDE43?? VFTR5?") EEPROM $30,("?NBHGY6???MJU78?") EEPROM $40,("?,KIO09??./L;P-?") EEPROM $50,("??'?[=?????]????") EEPROM $60,("?????????1?47???") ' Numeric keypad keys EEPROM $70,("0.2568??B+3-*9??") ' EEPROM $80,("0123456789ABCDEF") EEPROM $90,(ROM_A,ROM_A,ROM_A,ROM_A,ROM_A,ROM_A,ROM_A,ROM_A,ROM_B,ROM_B,ROM_B,ROM_B,ROM_B,ROM_B,ROM_B,ROM_B) EEPROM $A0,(ROM_C,ROM_C,ROM_C,ROM_C,ROM_C,ROM_C,ROM_C,ROM_C,ROM_D,ROM_D,ROM_D,ROM_D,ROM_D,ROM_D,ROM_D,ROM_D) setfreq em16 pause 2000 '************************************************ '* Sys Prompt * '* * '************************************************ tune 6,15,(16,18,24,18,16) serout 7,N19200_16,(0x5c,0x40,0x20,0x30) serout 7,N19200_16,("Linaxe v1") sys_prompt: 'tune 6,15,(16,32) 'serout 7,N19200_16,(0x5C,0x40,0x20,0x30,">") 'clear screen serout 7,N19200_16,(cr,lf,">") gosub get_8_bytes decode_prompt: hi2csetup i2cmaster,ROM_A,i2cslow_16,i2cword 'cycle through the ROMs for b8=0 to 31 w5=b8 * 9 hi2cin w5,(b12,b13,b14,b15,b16,b17,b18,b19,b20) if b0=b12 and b1=b13 and b2=b14 and b3=b15 and b4=b16 and b5=b17 and b6=b18 and b7=b19 then found_prog dec_loop: next b8 if b0="E" and b1="M" and b2="X" then boot_emaxe 'EMAXE - text editor if b0="M" and b1="K" then make_file 'MK - make files if b0="W" and b1="I" and b2="P" and b3="E" then wipe_all 'WIPE - erase all files if b0="C" and b1="C" then compile 'CMP - compile text files to executables if b0="R" and b1="M" then erase_file 'RM - erase files if b0="L" and b1="S" then ls 'LS - list all files if b0="P" then pong_initialize 'PONG 'if b0="S" then snap 'SNAP - take a picture serout 7,N19200_16,(cr,lf,"err") 'no program match found pause 2500 goto sys_prompt found_prog: if b20 <> "E" then dec_loop 'serout 7,N19200_16,(cr,lf,"loading",cr,lf) serout 7,N19200_16,("...") b8=b8+0x90 read b8,i2c_address b8=b8-0x90 b8=b8 // 8 pc0 = 8192 * b8 'pc1 = pc0 'PC1 is going to be the "base address register" for now, for use in GOTOs goto Executive 'wrongtype: ' serout 7,N19200_16,(cr,lf,"Not Executable") ; pause 2000 ' return 'goto sys_prompt '*********************************************** '* * '* Executive * '* * '*********************************************** bit0 = 1 bit2 = 1 Executive: cur_proc = 0 cur_pc = pc0 executing: gosub fetch_instruction goto executing '****************************************** '* Instruction Processor * '****************************************** fetch_instruction: 'Fetch an instruction ' gosub decode_rom hi2cin [i2c_address],cur_pc,(instr,oprnd0,oprnd1,oprnd2,oprnd3,oprnd4,oprnd5,oprnd6) ' serout 7,N19200_16, (cr,lf,#instr,#oprnd0,#oprnd1,#oprnd2,#oprnd3) 'Increment the current program counter cur_pc = cur_pc + 8 process_instruction: { branch instr,(opDO,opWHILE,opIF,opPRINTi,opADD,opSUB,opAND,opOR,opXOR,opMULT,opDIV,opADC,opGOTO,opGOSUB,opRETURN,opSOUND,opPEEK,opPOKE,opGETKEY,opSETPTR,opPRINTv,opEND,opREM) opDO: 'ptr = cur_proc * 41 'ptr = 0 'set ptr to beginning of stack ptr = do_stack_ptr_offset tempb0 = @ptrinc 'read value of do_stack_ptr, increment ptr to first byte of stack ptr = ptr + tempb0*2 'set ptr to empty stack location @ptr = cpc_msb ptr=ptr+1 @ptr = cpc_lsb ptr = ptr - 2 'set ptr back to do_stack_ptr @ptr = @ptr + 1 'increment do_stack_ptr return opWHILE: 'WHILE(A,<,var_type,var) 'comps: 0="=", 1=">", 2="<", 3="!=" select oprnd0 'retrieve variable value case 25 ptr = 25 tempb2 = @ptrinc tempb3 = @ptr hi2cin [RAM_B],tempw1,(tempb0) else ptr = oprnd0 tempb0 = @ptr endselect if oprnd2=0 then 'type 0 = normal a-z variable select oprnd3 case 25 ptr = 25 tempb2 = @ptrinc tempb3 = @ptr hi2cin [RAM_B],tempw1,(tempb1) else ptr = oprnd3 tempb1 = @ptr endselect else 'type 2 = immediate tempb1 = oprnd3 endif select oprnd1 case 0 '= if tempb0 != tempb1 then while_not_true gosub return_from_while case 1 '> if tempb0 <= tempb1 then while_not_true gosub return_from_while case 2 '< if tempb0 >= tempb1 then while_not_true gosub return_from_while case 3 '!= if tempb0 = tempb1 then while_not_true gosub return_from_while endselect return while_not_true: ptr = do_stack_ptr_offset 'set ptr to value of do stack ptr @ptr = @ptr - 1 ' decrement ptr because you're exiting a while loop return opIF: 'IF(A,comp,vartype,var,line number) select oprnd0 'retrieve variable value case 25 ptr = 25 tempb2 = @ptrinc tempb3 = @ptr hi2cin [RAM_B],tempw1,(tempb0) else ptr = oprnd0 tempb0 = @ptr endselect select oprnd2 'retrieve test value case 0 'type 0 = normal a-z variable ptr = oprnd3 tempb1 = @ptr case 1 'type 1 = pointer ptr = 25 tempb2 = @ptrinc tempb3 = @ptr hi2cin [RAM_B],tempw1,(tempb1) case 2 'type 2 = immediate tempb1 = oprnd3 endselect select oprnd1 case 0 '= if tempb0 != tempb1 then if_not_true gosub if_jump case 1 '> if tempb0 <= tempb1 then if_not_true gosub if_jump case 2 '< if tempb0 >= tempb1 then if_not_true gosub if_jump case 3 '!= if tempb0 = tempb1 then if_not_true gosub if_jump endselect return if_not_true: return opPRINTi: select oprnd0 case 1 serout 7,N19200_16,(oprnd1) case 2 serout 7,N19200_16,(oprnd1,oprnd2) case 3 serout 7,N19200_16,(oprnd1,oprnd2,oprnd3) case 4 serout 7,N19200_16,(oprnd1,oprnd2,oprnd3,oprnd4) case 5 serout 7,N19200_16,(oprnd1,oprnd2,oprnd3,oprnd4,oprnd5) else serout 7,N19200_16,(oprnd1,oprnd2,oprnd3,oprnd4,oprnd5,oprnd6) endselect return opPRINTv: 'sertxd("printv",#oprnd0,",",#oprnd1,cr,lf) if oprnd0 = 0 then select oprnd1 'type 0 = normal a-z variable case 25 ptr = 25 tempb2 = @ptrinc tempb3 = @ptr hi2cin [RAM_B],tempw1,(tempb1) else ptr = oprnd1 tempb1 = @ptr endselect 'sertxd("A:",#tempb1,cr,lf) serout 7,N19200_16,(tempb1) else serout 7,N19200_16,(#oprnd1) endif return opADD: 'sertxd("add",#oprnd0,",",#oprnd1,",",#oprnd2,",",#oprnd3,",",#oprnd4,cr,lf) gosub decode_args tempb0 = tempb0 + tempb1 goto write_results opSUB: gosub decode_args tempb0 = tempb0 - tempb1 goto write_results opAND: gosub decode_args tempb0 = tempb0 & tempb1 goto write_results opOR: gosub decode_args tempb0 = tempb0 | tempb1 goto write_results opXOR: gosub decode_args tempb0 = tempb0 ^ tempb1 goto write_results opMULT: gosub decode_args tempb0 = tempb0 * tempb1 goto write_results opDIV: gosub decode_args 'sertxd(cr,lf,#tempb0, " / ") tempb0 = tempb0 / tempb1 'sertxd(#tempb1,"=",#tempb0) goto write_results opADC: 'readadc 1,tempb0 'goto write_results tune 6, 20,($40,$60,$60,$60,$6C,$60,$60,$40,$6C,$6A,$6C,$40,$6C,$60,$6C,$60,$60,$60,$6C,$60,$60,$40,$6C,$6A,$6C,$40,$6C,$60,$6C,$60,$60,$60,$6C,$60,$60,$40,$6C,$6A,$6C,$E8) return 'temporarily knocking this out until i decide to implement it opGOTO: 'tempb0 = oprnd1 'oprnd1 should be MSB tempb0 = 0 tempb1 = oprnd0 'oprnd0 should be LSB tempw0 = tempw0*8 tempw0 = tempw0 + pc0 cpc_msb = tempb0 cpc_lsb = tempb1 return opGOSUB: ptr = gosub_stack_ptr_offset 'ptr = ptr + gosub_stack_ptr_offset tempb0 = @ptrinc 'read value of gosub_stack_ptr, increment ptr to first byte of stack ptr = tempb0*2 + ptr 'set ptr to empty stack location @ptr = cpc_msb ptr=ptr+1 @ptr = cpc_lsb ptr = ptr - 2 'set ptr back to do_stack_ptr @ptr = @ptr + 1 'increment gosub_stack_ptr 'now actually perform the GOTO tempb0 = 0 tempb1 = oprnd0 tempw0 = tempw0*8 tempw0 = tempw0 + pc0 cpc_msb = tempb0 cpc_lsb = tempb1 return opRETURN: ptr = gosub_stack_ptr_offset 'set ptr to value of gosub stack ptr @ptr = @ptr - 1 'read value of gosub_stack_ptr, decrement ptr because it's a "return" ptr = @ptr*2 + ptr 'set ptr to value of first byte of return address cpc_msb = @ptrinc 'read return address MSB cpc_lsb = @ptr 'read return address LSB return opSOUND: 'serout 6,N2400_16,(oprnd0,oprnd1,oprnd2,oprnd3,oprnd4,oprnd5,oprnd6) tune 6,15,(oprnd0) 'serout 7,N19200_16,("snd:",#oprnd0,",",#oprnd1) 'OUTPUT PIN6 IS THE SPEAKER PIN return opPEEK: tempb2 = oprnd1 tempb3 = oprnd2 hi2cin [RAM_B],tempw1,(tempb0) goto write_results opPOKE: tempb2 = oprnd1 'get the i2c address to write to tempb3 = oprnd2 select oprnd0 case 25 ptr = 25 tempb4 = @ptrinc tempb5 = @ptr swap tempw1, tempw2 hi2cin [RAM_B],tempw2,(tempb0) else ptr = oprnd0 tempb0 = @ptr endselect writei2c tempw1,(tempb0) return opGETKEY: kbin tempb0 select oprnd0 case 25 ptr = 25 tempb2 = @ptrinc tempb3 = @ptr hi2cout [RAM_B],tempw1,(tempb0) else ptr = cur_proc * 42 + oprnd0 @ptr = tempb0 endselect return opSETPTR: gosub decode_args ptr = z_offset @ptr=tempb0 ptr = ptr + 1 @ptr=tempb1 return opEND: serout 7,N19200_16,(cr,lf,"DONE") gosub getakey goto sys_prompt opREM:'sertxd("comment",cr,lf) return } decode_args: { select oprnd1 case 0 'type 0 = normal a-z variable if oprnd2 <> 25 then ptr = oprnd2 tempb0 = @ptr else ptr = 25 tempb2 = @ptrinc tempb3 = @ptr hi2cin [RAM_B],tempw1,(tempb0) endif case 1 'type 2 = immediate tempb0 = oprnd2 endselect 'oprnd3 is the "type" of the 2nd operand, oprnd4 is the 2nd operand's value select oprnd3 case 0 if oprnd4 <> 25 then ptr = oprnd4 tempb1 = @ptr else ptr = 25 'read value of pointer tempb2 = @ptrinc 'tempb2 = MSB of tempw1 (and now pointer) tempb3 = @ptr 'tempb3 = LSB of tempw1 (and now pointer) hi2cin [RAM_B],tempw1,(tempb1) 'read (pointer) into tempb1 endif case 1 tempb1 = oprnd4 'load immediate value into tempb1 endselect select oprnd0 case 25 ptr = 25 tempb2 = @ptrinc tempb3 = @ptr else ptr = oprnd0 endselect return} write_results: {select oprnd0 case 25 hi2cout [RAM_B],tempw1,(tempb0) else @ptr = tempb0 endselect return 'return from original instruction } return_from_while: { ptr = do_stack_ptr_offset 'set ptr to value of while stack ptr @ptr = @ptr 'read value of while_stack_ptr ptr = @ptr*2 + ptr 'set ptr to value of first byte of return address cpc_msb = @ptrinc 'read return address MSB cpc_lsb = @ptr 'read return address LSB return } if_jump: { tempb2 = oprnd4 tempb3 = oprnd5 tempw1 = tempw1*8 'multiply by 8 to go to appropriate line number cpc_msb = tempb2 cpc_lsb = tempb3 return } '****************************** '* ROM Decoding * '****************************** #REM decode_rom: { select cur_proc case 0 if bit8=0 AND bit9=0 then set_a if bit8=1 AND bit9=0 then set_b if bit8=0 AND bit9=1 then set_c if bit8=1 AND bit9=1 then set_d case 1 if bit10=0 AND bit11=0 then set_a if bit10=1 AND bit11=0 then set_b if bit10=0 AND bit11=1 then set_c if bit10=1 AND bit11=1 then set_d case 2 if bit12=0 AND bit13=0 then set_a if bit12=1 AND bit13=0 then set_b if bit12=0 AND bit13=1 then set_c if bit12=1 AND bit13=1 then set_d endselect set_a: i2c_address = rom_a return set_b: i2c_address = rom_b return set_c: i2c_address = rom_c return set_d: i2c_address = rom_d return } #ENDREM '************************************ '* System Utilities * '************************************ 'LS: List all Programs 'ls: 'CP ## ##: Copy slot ## to slot ## 'cp: 'RM ##: Delete the current program in slot ## 'rm: 'RX ##: Receive a program into slot ## 'rm: 'TX ##: Transmit a program in slot ## 'tx: 'UP #### ####: Upload the contents of RAM from #### to #### 'up: 'SNAP: Take a picture '1 picture =16k = 4 file blocks '1 picture can be held in RAM at a time (upper 16k) 'snap: 'MK: Create a file 'EMAXE: Text Editor 'current programs can be up to 8k long 'instruction tolkens { #rem opDO=0, opWHILE=1, opIF=2, opPRINTi=3, opADD=4, opSUB=5, opAND=6, opOR=7, opXOR=8, opMULT=9, opDIV=10, opADC=11, opGOTO=12, opGOSUB=13, opRETURN=14, opSOUND=15, opPEEK=16, opPOKE=17, opGETKEY=18, opSETPTR=19, opPRINTv=20, opEND=21, opREM=22 #endrem } decode_command: {if b0="D" and b1="O" then dec_do 'DO="DO" if b0="W" then dec_while 'WHILE="WHILE" if b0="A" and b1="D" then dec_add 'ADD="ADD[.A,HFF,.C]" = A <= 0xFF + C if b0="S" and b1="U" then dec_sub 'SUB="SUB" if b0="I" then dec_if 'IF="IF" if b0="M" then dec_mlt 'MULT="MLT" if b2="V" then dec_div 'DIV="DIV" if b0="P" and b4="I" then dec_printi 'PRINTi="PRNTI" (print immediate) if b0="P" and b4="V" then dec_printv 'PRINTv="PRNTV" (print variable) if b0="A" and b1="N" then dec_and 'AND="AND" if b0="O" then dec_orr 'OR="ORR" if b0="X" then dec_xor 'XOR="XOR" if b0="G" and b2="S" then dec_gosub 'GOSUB if b0="R" and b2="T" then dec_return 'RETURN="RETURN" if b0="S" and b1="E" then dec_setptr 'SETPTR if b0="T" and b1="G" then dec_adc 'ADC="ADC" 'ADC has been replaced by TG (topgun theme) if b0="G" and b2="T" then dec_goto 'GOTO="GOTO" if b0="S" and b1="N" then dec_sound 'SND if b0="P" and b1="E" then dec_peek 'PEEK="PEEK" if b0="P" and b1="O" then dec_poke 'POKE="POKE" if b0="G" and b1="K" then dec_getkey 'GKEY if b0="E" and b1="N" then dec_end 'END if b0="R" and b2="M" then dec_comment 'COMMENT 'serout 7,N19200_16,(cr,lf,"Err:",b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10) serout 7,N19200_16,("Err") pause 5000 'goto sys_prompt return} dec_do: {'sertxd("DO") b0=0 return} dec_while: {'sertxd("WHILE") 'WHILE(A,<,var_type,var) 'comps: 0="=", 1=">", 2="<", 3="!=" b0=1 b1=b6-65 select b7 case "e" 'equal b2=0 case "g" 'greater than b2=1 case "l" 'less than b2=2 case "n" 'not equal to b2=3 endselect if b8="." then b3=0 b4=b9-65 else b3=1 b16=b9 b17=b10 gosub dehexify b4=b16 endif return} dec_if: {'sertxd("IF") 'IF(A,comp,vartype,var,line number) b0=2 b1=b3-65 select b5 case "E" 'equal b2=0 case "G" 'greater than b2=1 case "L" 'less than b2=2 case "N" 'not equal to b2=3 endselect if b7="." then b3=0 b4=b8-65 else b3=1 b16=b8 b17=b9 gosub dehexify b4=b16 endif b16=b11 b17=b12 gosub dehexify b5=b16 return} dec_printi: {'sertxd("PRNTi",cr,lf) b0=3 b1=b6-48 b2=b8 b3=b9 b4=b10 b5=b11 b6=b12 b7=b13 return} dec_add: {'sertxd("ADD",cr,lf) 'ADD(destination_var,type1,val1,type2,val2) = 2 b0=4 'ADD=2 gosub dec_rtype return} dec_sub: {'sertxd("SUB") b0=5 gosub dec_rtype return} dec_and: {'sertxd("AND") b0=6 gosub dec_rtype return} dec_orr: {'sertxd("ORR") b0=7 gosub dec_rtype return} dec_xor: {'sertxd("XOR") b0=8 gosub dec_rtype return} dec_mlt: {'sertxd("MLT") b0=9 gosub dec_rtype return} dec_div: {'sertxd("DIV",cr,lf) b0=10 gosub dec_rtype return} dec_adc: {'sertxd("adc") b0=11 'b1=b5-65 return} dec_goto: {'sertxd("goto",cr,lf) b0=12 b16=b5 b17=b6 gosub dehexify b1=b16 return} dec_gosub: 'Format: GOSUB[FF] {'sertxd("gosub") b0=13 b16=b6 b17=b7 gosub dehexify b1=b16 return} dec_return: {'sertxd("return") b0=14 return} dec_sound: 'sertxd("sound") 'format: SND([0-F],[00-FF]) b0=15 'store sound opcode b16=b4 'decode note b17=b5 gosub dehexify b1=b16 'store note 'b16=b6 'figure out note to play 'b17=b7 'gosub dehexify 'b2=b16 'store note to play return dec_peek: {'sertxd("peek") b0=16 b1=b5-65 b16=b7 b17=b8 gosub dehexify b2=b16 b16=b9 b17=b10 gosub dehexify b3=b17 return} dec_poke: {'sertxd("poke") b0=17 b1=b5-65 b16=b7 b17=b8 gosub dehexify b2=b16 b16=b9 b17=b10 gosub dehexify b3=b16 return} dec_getkey: {'sertxd("gkey") b1=b5-65 b0=18 return} dec_setptr: {'sertxd("setptr") b0=19 if b7="." then b1=0 b2=b8-65 b3=b9-65 else b1=1 b16=b8 b17=b9 gosub dehexify b2=b16 b16=b10 b17=b11 gosub dehexify b3=b16 endif return} dec_printv: {'sertxd("prntv",cr,lf) b0=20 b1=0 'for now, sets it so it sends the value verbatim to the screen b2=b6-65 return } dec_end: 'sertxd("end",cr,lf) b0=21 return dec_comment: 'sertxd("cmnt",cr,lf) b0=22 return '==================R-Type decoding===================== {' decodes R-type instructions to save space '====================================================== dec_rtype: b1=b4-65 'compute offset of destination variable if b6="." then r1 b2=1 'set var_type=immediate b16=b7 b17=b8 gosub dehexify b3=b16 if b10="." then b4=0 b5=b11-65 else b4=1 b16=b11 b17=b12 gosub dehexify b5=b16 endif return r1: b2=0 'set var_type=reg b3=b7-65 'compute offset of val1 if b9="." then b4=0 b5=b10-65 else b4=1 b16=b10 b17=b11 gosub dehexify b5=b16 endif return } '========================================================== '======================Dehexification============================= {'takes in a hex byte (i.e. for 9F, b16="9",b17="F") 'returns a binary byte at b16 (i.e. b16=159) dehexify: if b16>60 then dethexone b16=b16-48 b16=b16*16 dehexifytwo: if b17>60 then dethextwo b17=b17-48 b16=b16 | b17 return dethextwo: b17=b17-55 b16=b16 | b17 return dethexone: b16=b16-55 b16=b16*16 goto dehexifytwo } '================================================================== ' "."=> type=A-Y ' "Z" => pointer ' "i"=> type=immediate '===================================================================== ' MAKE FILE '===================================================================== 'This is used to create a file make_file: for b0 = 1 to 31 w8=b0 * 9 hi2cin [ROM_A],w8,(b1) if b1=0 then found_empty next b0 serout 7,N19200_16,(cr,lf,"Full") pause 1000 goto sys_prompt found_empty: serout 7,N19200_16,(cr,lf,"File Name:") b26 = b0 gosub get_8_bytes hi2cout [ROM_A],w8,(b0,b1,b2,b3,b4,b5,b6,b7,"T") 'FIXME: change to allow different file types to be created, rather than just text serout 7,N19200_16,(cr,lf,"File Created",cr,lf,"zeroing...") b0 = b26 gosub wipe_one pause 1000 goto sys_prompt '==================================================================== ' WIPE ALL '==================================================================== 'this will wipe the entire file table wipe_all: for b0 = 0 to 31 w8=b0*9 pause 100 hi2cout [ROM_A],w8,(0,0,0,0,0,0,0,0,0) next b0 'serout 7,N19200_16,(cr,lf,"disk wiped") serout 7,N19200_16,(cr,lf,"done") pause 1000 goto sys_prompt '===================================================================== ' wipe one and write all 0's '===================================================================== 'completely zeros out file number pointed to by b0 (i.e. if b0=3, it wipes file A:3) wipe_one: b0 = b0 + 0x90 read b0,b2 'look up ROM address b0 = b0 - 0x90 b1 = b0 // 8 'calculate which slot in rom w9 = 8192 * b1 for w8 = 0 to 1023 'perform 1024 8-byte transfers hi2cout [b2],w9,(0,0,0,0,0,0,0,0) 'write out 16 byte block pause 100 w9 = w9 + 8 'increment write_pointer next w8 return '===================================================================== ' Text Editor '===================================================================== 'FIX WITH REAL VALUES - USES UPPER 32K OF MEMORY ON I2C CHIP: $9C40-$FFFF, divided into 160-byte pages of 8 'lines of code (16 bytes per line) symbol line=s_w0 symbol offset=b26 boot_emaxe: ' hi2csetup i2cmaster,RAM_A,i2cslow_16,i2cword serout 7,N19200_16,(cr,lf,"file:") gosub get_8_bytes hi2csetup i2cmaster,ROM_A,i2cslow_16,i2cword for b27=1 to 31 'b27 always holds the file slot w5=b27 * 9 hi2cin w5,(b12,b13,b14,b15,b16,b17,b18,b19,b20) if b0=b12 and b1=b13 and b2=b14 and b3=b15 and b4=b16 and b5=b17 and b6=b18 and b7=b19 then found_file emx_floop: next b27 'serout 7,N19200_16,(cr,lf,"invld file") 'no program match found serout 7,N19200_16,(cr,lf,"err") pause 1000 goto sys_prompt found_file: if b20 <> "T" then emx_floop ' serout 7,N19200_16,(cr,lf,"ext err") ' pause 1000 ' goto sys_prompt ' endif b27 = b27 + 0x90 read b27,b21 'lookup destination ROM address b27 = b27 - 0x90 b8 = b27 // 8 'figure out which file on the rom is the right one 'serout 7,N19200_16,(cr,lf,"loading...") serout 7,N19200_16,(cr,lf,"...") 'now transfer the 8k block from the appropriate rom to RAM_A line = b8 * 8192 'calculate starting position w9 = 0 'destination starting point for w8 = 0 to 511 'perform 512 16-byte transfers hi2cin [b21],line,(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15) 'read in 16 bytes line = line + 16 'increment read_pointer hi2cout [RAM_A],w9,(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15) 'write out 16 byte block if b0="E" and b1="O" and b2="F" then done_loading 'pause 50 w9 = w9 + 16 'increment write_pointer next w8 done_loading: line=32 offset=0 hi2csetup i2cmaster,RAM_A,i2cslow_16,i2cword pause 450 emaxe: gosub displaypage gk3: 'pause 500 gosub getakey 'if b24 = 0 then gk3 'loop until you get a key pause 200 select case b24 case 117 line=line-16 'up key goto text1 case 114 'down key line=line+16 goto text1 case 118 'escape key goto emaxe_exit: case 107 'left arrow if offset=0 then text1 offset=offset-1 goto text1 case 116 'right arrow if offset=15 then text1 offset=offset+1 goto text1 case 102 'backspace if offset=0 then text1 offset=offset-1 line=line+offset hi2cout line,(32) 'just output a space line=line-offset goto text1 case 90 line=line+16 offset=0 goto text1 endselect read b24,b25 'look up ascii value line=line+offset hi2cout line,(b25) line=line-offset if offset <> 15 then offset=offset+1 else line=line+16 offset=0 endif text1: 'gosub displaypage goto emaxe emaxe_exit: serout 7,N19200_16,(0x5C,0x40,0x20,0x30,"Rtn[0]",cr,lf,"Save[1]",cr,lf,"Exit[2]" ) emx1: 'pause 500 gosub getakey 'if b24=0 then emx1 read b24,b25 if b25 = "2" then sys_prompt if b25 <> "1" then emaxe 'goto emaxe emaxe_save: serout 7,N19200_16,(cr,lf,"1...") b27 = b27 + 0x90 read b27,b21 b27 = b27 - 0x90 b25 = b27 // 8 'figure out which file on the rom is the right one s_w1 = b25 * 8192 w9 = 0 'destination starting point for w8 = 0 to 511 'perform 512 16-byte transfers hi2cin [RAM_A],w9,(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15) 'read in 16 bytes w9 = w9 + 16 'increment read_pointer hi2cout [b21],s_w1,(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15) 'write out 16 byte block pause 50 if b0="E" and b1="O" and b2="F" then done_saving s_w1= s_w1 + 16 'increment write_pointer next w8 done_saving: goto emaxe '=============================================================================================== '=============================================================================================== ' Display Page Routine '=============================================================================================== displaypage: pause 200 'pause to prevent LCD from erasing first line serout 7,N19200_16,(0x5C,0x40,0x20,0x30) 'clear screen 'line=line-40 'set location back two lines line=line-32 b23=33 for b22=1 to 8 gosub word_to_3_dig_hex serout 7,N19200_16,(b2,b3,b4,":") 'hi2cin [RAM_A],line,(b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20,b21) 'reads 1st line of code hi2cin [RAM_A],line,(b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,b16,b17) serout 7,N19200_16,(b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,b16,b17,0x5C,0x42,32,b23) 'serout 7,N19200_16,(b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20,b21,0x5C,0x42,32,b23) 'prints first line of code 'line=line+20 line = line + 16 b23=b23+1 next b22 'line=line-120 line=line-96 b2=offset+36 serout 7,N19200_16,(0x5c,0x42,b2,34,0x5c,0x5f) 'display cursor return '================================================================================================= '===================================================== ' Keyboard Input '===================================================== getakey: pause 400 hi2csetup i2cmaster,SLAVE,i2cfast_16,i2cbyte hi2cin 0,(b23,b24) 'sertxd(#b23,",",#b24,cr,lf) if b23 <> 1 then b24 = 0 'if tempb0 != 1, then set received byte to 0 else ' serout 7,N19200_16,("got a key") hi2cout 0,(0) endif 'reset keyboard status byte hi2csetup i2cmaster,RAM_A,i2cslow_16,i2cword if b24 = 0 then getakey return '======================================================== word_to_3_dig_hex: w4=line/16 b5=w4/256 'most significant digit b5=b5+0x80 read b5,b2 w4=w4 // 256 b5=w4/16 'middle digit b5=b5+0x80 read b5,b3 b5=w4//16 'least significant digit b5=b5+0x80 read b5,b4 return get_8_bytes: w0=0 w1=0 w2=0 w3=0 s1: 'pause 500 gosub getakey 'if b24=0 then s1 'pause 200 if b24 = 90 then 'should detect "enter" key return endif read b24, b25 b0 = b25 serout 7,N19200_16,(b0) s2: 'pause 500 gosub getakey 'if b24=0 then s2 'pause 200 if b24 = 90 then return endif read b24, b25 b1 = b25 serout 7,N19200_16,(b1) s3: 'pause 500 gosub getakey 'if b24=0 then s3 'pause 200 if b24 = 90 then return endif read b24, b25 b2 = b25 serout 7,N19200_16,(b2) s4: 'pause 500 gosub getakey 'if b24=0 then s4 'pause 200 if b24 = 90 then return endif read b24, b25 b3 = b25 serout 7,N19200_16,(b3) s5: 'pause 500 gosub getakey 'if b24=0 then s5 'pause 200 if b24 = 90 then return endif read b24, b25 b4 = b25 serout 7,N19200_16,(b4) s6: 'pause 500 gosub getakey 'if b24=0 then s6 'pause 200 if b24 = 90 then return endif read b24, b25 b5 = b25 serout 7,N19200_16,(b5) s7: 'pause 500 gosub getakey 'if b24=0 then s7 'pause 200 if b24 = 90 then return endif read b24, b25 b6 = b25 serout 7,N19200_16,(b6) s8: 'pause 500 gosub getakey 'if b24=0 then s8 'pause 200 if b24 = 90 then return endif read b24, b25 b7 = b25 serout 7,N19200_16,(b7) stall_prompt: gosub getakey if b24 <> 90 then stall_prompt return '============================================ ' Compiler '============================================ 'This will take in a text file and spit out 'an executable file. 'X1. take in the name of a text file 'X2. check to make sure it is a text file (error if not) 'X3. search if there are any blank slots, if there are, make a new file 'X4. use same name as text file, but make it executable ("E") type 'X5. go through text file line-by-line (start at line 0), decoding and writing each line 'X6. when you reach EOF, exit out { compile: serout 7,N19200_16,(cr,lf,"F?") gosub get_8_bytes hi2csetup i2cmaster,ROM_A,i2cslow_16,i2cword for b27=0 to 31 'b27 always holds the file slot w5=b27 * 9 hi2cin w5,(b12,b13,b14,b15,b16,b17,b18,b19,b20) if b0=b12 and b1=b13 and b2=b14 and b3=b15 and b4=b16 and b5=b17 and b6=b18 and b7=b19 and b20="T" then found_target next b27 serout 7,N19200_16,(cr,lf,"err") 'no program match found pause 1000 goto sys_prompt found_target: for b12 = 1 to 31 w8=b12 * 9 hi2cin [ROM_A],w8,(b13) if b13=0 then found_empty_slot next b12 serout 7,N19200_16,(cr,lf,"full") pause 1000 goto sys_prompt found_empty_slot: hi2cout [ROM_A],w8,(b0,b1,b2,b3,b4,b5,b6,b7,"E") b26 = w8 / 9 b26 = b26 + 0x90 read b26,b21 'b21 is now holding rom address of destination b26 = b26 - 0x90 b25 = b26 // 8 'figure out which file on the rom is the right one s_w1 = b25 * 8192 's_w1 is now holding pointer to starting address of destination b27 = b27 + 0x90 read b27,b22 'b22 is now holding ROM address of original file b27 = b27 - 0x90 b24 = b27 // 8 'figure out which file on the rom is the right one s_w0 = b24 * 8192 's_w0 is now holding pointer to starting address of original file compile_loop: hi2cin [b22],s_w0,(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15) 'read in 1 line of raw code pause 10 if b0=255 then compile_loop if b0="E" and b1="O" and b2="F" then done_compiling 'detected End Of File (EOF) gosub decode_command hi2cout [b21],s_w1,(b0,b1,b2,b3,b4,b5,b6,b7) pause 100 s_w0 = s_w0 + 16 s_w1 = s_w1 + 8 goto compile_loop done_compiling: hi2cout [b21],s_w1,(21) 'write "END" as last byte serout 7,N19200_16,(cr,lf,"done") pause 1000 goto sys_prompt 'then loop through until you see all 0's, decoding each line } '===================================================================================================== erase_file: serout 7,N19200_16,(cr,lf,"F?:") gosub get_8_bytes serout 7,N19200_16,(cr,lf,"ext:") s9: 'pause 500 gosub getakey 'if b24=0 then s9 read b24,b24 hi2csetup i2cmaster,ROM_A,i2cslow_16,i2cword for b27=0 to 31 'b27 always holds the file slot w5=b27 * 9 hi2cin [ROM_A],w5,(b12,b13,b14,b15,b16,b17,b18,b19,b20) if b0=b12 and b1=b13 and b2=b14 and b3=b15 and b4=b16 and b5=b17 and b6=b18 and b7=b19 and b20=b24 then found_file_to_del next b27 serout 7,N19200_16,(cr,lf,"err") pause 1500 goto sys_prompt found_file_to_del: hi2cout [ROM_A],w5,(0,0,0,0,0,0,0,0,0) pause 100 serout 7,N19200_16,("done") pause 1500 goto sys_prompt '======================================================================================== ' LS '======================================================================================== 'Lists all of the currently available files ls: serout 7,N19200_16,(cr,lf) b8=0 for b27=1 to 31 'b27 always holds the file slot w5=b27 * 9 hi2cin [ROM_A],w5,(b12,b13,b14,b15,b16,b17,b18,b19,b20) if b12 <> 0 and b12 <> 255 then print_name ls1: next b27 serout 7,N19200_16,("...") gosub getakey goto sys_prompt print_name: b8 = b8 + 1 serout 7,N19200_16,(b12,b13,b14,b15,b16,b17,b18,b19,".",b20,cr,lf) if b8 <> 7 then ls1 b8=0 serout 7,N19200_16,("...") gosub getakey serout 7,N19200_16,(0x5C,0x40,0x20,0x30) goto ls1 '================================= ' ' PONG ' '================================= symbol ball_x = b3 symbol ball_y = b4 'b5=left_paddle_height 'b6=right_paddle_height symbol moving_left = bit0 symbol moving_up = bit1 symbol handicap = bit2 pong_initialize: b5=36 b6=36 b7=0 b8=0 ball_x=44 ball_y=36 moving_left=1 moving_up=1 pong_main: gosub move_paddle pong_move_ball: if ball_x = 0x37 or ball_x=0x20 then moving_left=~moving_left endif if ball_y = 0x20 or ball_y=0x27 then moving_up = ~moving_up endif if moving_left=0 then ball_x=ball_x+1 else ball_x=ball_x-1 endif if moving_up=1 then ball_y=ball_y+1 else ball_y=ball_y-1 endif if ball_x = 0x20 and b5 <> ball_y then b8=b8+1 endif if ball_x = 0x37 and b6 <> ball_y then b7=b7+1 'tune 6,15,(16) endif 'position cursor: 0x5C,0x42,, serout 7,N19200_16,(0x5c,0x40,0x20,0x30,0x5c,0x42,0x20,b5,"|",0x5c,0x42,0x37,b6,"|",0x5c,0x42,b3,b4,"*") serout 7,N19200_16,(0x5c,0x42,0x28,0x28,#b7,0x5c,0x42,0x30,0x28,#b8) pause 500 if b8=10 then serout 7,N19200_16,("LOSE") pause 5000 goto sys_prompt else if b7=10 then serout 7,N19200_16,("WIN") pause 5000 goto sys_prompt endif goto pong_main move_paddle: hi2csetup i2cmaster,SLAVE,i2cfast_16,i2cbyte hi2cin 0,(b23,b24) handicap = ~handicap if b23 <> 1 then b24 = 0 'if tempb0 != 1, then set received byte to 0 else ' serout 7,N19200_16,("got a key") hi2cout 0,(0) endif 'reset keyboard status byte if b24 = 114 and b5 <> 39 then b5=b5+1 'detected up else if b24 = 117 and b5 <> 32 then b5=b5-1 endif if moving_up=1 and b6 <> 39 and handicap=1 then b6=b6+1 else if moving_up=0 and b6 <> 32 and handicap=1 then b6=b6-1 endif return snap: 'hi2csetup i2cmaster,SLAVE,i2cfast_16,i2cbyte ' hi2cout [SLAVE],0,(64) ' hi2csetup i2cslave,%11110000 snap_wait: ' pause 500 ' get 64,b1 ' if b1=1 then sys_prompt 'if status=done, reboot system ' goto snap_wait