@ hence core lib core: core_mem: .define CORE_MEM_PRG, (0 * 1024) .define CORE_MEM_ST, (32 * 1024) .define CORE_MEM_MEM, (40 * 1024) .define CORE_MEM_OUT, (56 * 1024) .define CORE_MEM_CHR, (56 * 1024 + 1) .define CORE_MEM_KEY, (56 * 1024 + 2) core_reg: .define CORE_REG_PC, 0x0 .define CORE_REG_OPC, 0x1 .define CORE_REG_ARG, 0x2 .define CORE_REG_S, 0x3 .define CORE_REG_SP, 0x4 .define CORE_REG_A, 0x5 .define CORE_REG_B, 0x6 .define CORE_REG_C, 0x7 .define CORE_REG_D, 0x8 core_alu: .define CORE_ALU_NOT, 0x00 .define CORE_ALU_AND, 0x01 .define CORE_ALU_OR, 0x02 .define CORE_ALU_XOR, 0x03 .define CORE_ALU_LSH, 0x04 .define CORE_ALU_RSH, 0x05 .define CORE_ALU_ADD, 0x06 .define CORE_ALU_SUB, 0x07 .define CORE_ALU_MUL, 0x08 .define CORE_ALU_DIV, 0x09 .define CORE_ALU_CMP, 0x0a .define CORE_ALU_EQ, 0x0b .define CORE_ALU_LT, 0x0c .define CORE_ALU_GT, 0x0d .define CORE_ALU_LEQ, 0x0e .define CORE_ALU_GEQ, 0x0f .define CORE_ALU_BOL, 0x10 .define CORE_ALU_INV, 0x11 .define CORE_ALU_RND, 0x12 @ hence standard lib STD: .define STD_U8_MAX, 0xff .define STD_U16_MAX, 0xffff .macro std_stop ts 0xffff tlr CORE_REG_PC .macroend forth: .define FORTH_MEM_INPUT_SIZE, 16 .define FORTH_MEM_INPUT_DYN_SIZE, CORE_MEM_MEM .define FORTH_MEM_INPUT_START, (FORTH_MEM_INPUT_DYN_SIZE + 1) .define FORTH_MEM_INPUT_END, (FORTH_MEM_INPUT_START + FORTH_MEM_INPUT_SIZE) .define jump_main, (CORE_MEM_ST - 3 - 1) ts jump_main tlr CORE_REG_PC end_input: dbg main: @ loop body loop: @ read key from stdin ts CORE_MEM_KEY get @ check if key is newline (0x0a) tlr CORE_REG_D @ store in register D because register A is used later on tlr CORE_REG_A @ store in register A as input for ALU ts "\n" @ store newline in TMP tlr CORE_REG_B @ store newline in register B as input for ALU ts CORE_ALU_EQ @ ALU equal operation alu @ run ALU @ go back to loop start if pressed key is newline tlr CORE_REG_A @ store result of ALU operation in TMP @ ts loop @ load memory address of loop start into TMP ts 0 tls ts jump_switch tls ts end_input tlrc CORE_REG_PC @ set register PC to loop start address if result is true pop tlr CORE_REG_A ts 0 tlrc CORE_REG_C @ print out char tsr CORE_REG_D @ get char tlr CORE_REG_A @ load char into register A ts CORE_MEM_CHR @ set TMP to char print memory address set @ print char @ increment counter by one tsr CORE_REG_C tlr CORE_REG_A ts 1 tlr CORE_REG_B ts CORE_ALU_ADD alu tlr CORE_REG_C tlr CORE_REG_A ts FORTH_MEM_INPUT_SIZE tlr CORE_REG_B ts CORE_ALU_LT alu tlr CORE_REG_A ts loop tlrc CORE_REG_PC ts "\n" tlr CORE_REG_A ts CORE_MEM_CHR set tsr CORE_REG_C tls dbg pop ts 0 tlr CORE_REG_C ts loop tlr CORE_REG_PC @ .std_stop @ set PC to maximum for u16 and therefore stops program execution ts 0xffff @ load 0xffff into TMP tlr CORE_REG_PC @ store value of TMP into register PC jump_switch: dbg .org jump_main ts main tlr CORE_REG_PC