## Copyright (C) 2016 Jeremiah Orians ## This file is part of stage0. ## ## stage0 is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## stage0 is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with stage0. If not, see . # :start 0D00002E # FALSE R14 ; R14 will be storing our current address E0002D2F0118 # LOADUI R15 $end ; We will be using R15 for our stack # ;; Main program functionality # ;; Reads in Tape_01 and writes out results to Tape_02 # ;; Accepts no arguments and HALTS when done # :main # ;; Prep TAPE_01 E0002D201100 # LOADUI R0 0x1100 42100000 # FOPEN_READ # ;; Prep TAPE_02 E0002D201101 # LOADUI R0 0x1101 42100001 # FOPEN_WRITE # ;; Perform main loop # :main_0 E0002D211100 # LOADUI R1 0x1100 ; Read from tape_01 42100100 # FGETC ; Read a Char # ;; Check for EOF E000A0100000 # CMPSKIPI.GE R0 0 3C000010 # JUMP @main_1 # ;; Process that byte E0002D0F0022 # CALLI R15 @dehex # ;; Increment address E1000FEE0001 # ADDUI R14 R14 1 # ;; Get next byte 3C00ffdc # JUMP @main_0 # :main_1 # ;; Close up as we are done E0002D201100 # LOADUI R0 0x1100 ; Close TAPE_01 42100002 # FCLOSE E0002D201101 # LOADUI R0 0x1101 ; Close TAPE_02 42100002 # FCLOSE FFFFFFFF # HALT # ;; Dehex functionality # ;; Accepts byte in R0 # ;; Prints address every 4th byte # ;; Alters R0 # ;; Returns to whatever called it # :dehex 5a 0902001F # PUSHR R1 R15 ; Preserve R1 0902000F # PUSHR R0 R15 ; Save byte until after address E100B00E0003 # ANDI R0 R14 3 ; Get mod 4 of address E0002D211101 # LOADUI R1 0x1101 ; We want it on TAPE_02 E000A0200000 # CMPSKIPI.E R0 0 ; if not zero 3C000028 # JUMP @dehex_0 ; Skip placing address # ;; Prepend new line E0002D20000a # LOADUI R0 10 ; First print line feed 42100200 # FPUTC ; Write it # ;; Write out address 0900040E # COPY R0 R14 ; Prep for call E0002D0F0030 # CALLI R15 @hex32 ; Let it handle the details # ;; Write out : char E0002D20003a # LOADUI R0 58 ; Prep 42100200 # FPUTC ; Write it # ;; Write out tab E0002D200009 # LOADUI R0 9 ; Prep 42100200 # FPUTC ; Write it # :dehex_0 a0 0902800F # POPR R0 R15 ; Restore byte received E0002D0F003a # CALLI R15 @hex8 ; Use a subset E0002D200020 # LOADUI R0 32 ; Prep for writing space 42100200 # FPUTC ; Write it 0902801F # POPR R1 R15 ; Restore R1 0D01001F # RET R15 ; Return to caller # ;; hex32 functionality # ;; Accepts 32bit value in R0 # ;; Require R1 to be the device to write the results # ;; Returns to whatever called it # :hex32 bc 0902000F # PUSHR R0 R15 E0002D600010 # SR0I R0 16 ; Do high word first E0002D0F0004 # CALLI R15 @hex16 0902800F # POPR R0 R15 # :hex16 d0 0902000F # PUSHR R0 R15 E0002D600008 # SR0I R0 8 ; Do high byte first E0002D0F0004 # CALLI R15 @hex8 0902800F # POPR R0 R15 # :hex8 e4 0902000F # PUSHR R0 R15 E0002D600004 # SR0I R0 4 ; Do high nybble first E0002D0F0004 # CALLI R15 @hex4 0902800F # POPR R0 R15 # :hex4 f8 E100B000000f # ANDI R0 R0 0x000F ; isolate nybble E1000F000030 # ADDUI R0 R0 48 ; convert to ascii E000A0400039 # CMPSKIPI.LE R0 57 ; If nybble was greater than '9' E1000F000007 # ADDUI R0 R0 7 ; Shift it into 'A' range of ascii 42100200 # FPUTC ; Print char 0D01001F # RET R15 ; Get next nybble or return if done # ;; Where we are putting our stack # :end 118