stage0/stage1/SET.hex0

432 lines
12 KiB
Plaintext

## This file is part of stage0.
##
## stage0 is free software: you an 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 <http://www.gnu.org/licenses/>.
# :start
2D2F0394 # LOADUI R15 $stack ; Put stack at end of program
# ;; We will be using R14 for our condition codes
# ;; We will be using R13 for storage of Head
# ;; Main program
# ;; Reads contents of Tape_01 and writes desired contents onto Tape_02
# ;; Accepts no arguments and HALTS when done
# :main
# ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100
42100000 # FOPEN_READ
# ;; Prepare to Read File
0D00002E # FALSE R14
0D000021 # FALSE R1
2D0F0018 # CALLI R15 @ReadFile
# ;; Done reading File
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE
# ;; Enter Editor Loop
090005D1 # MOVE R13 R1 ; Set R13 to Head
2D0F0134 # CALLI R15 @EditorLoop
# ;; And We are Done
FFFFFFFF # HALT
# ;; Readfile function
# ;; Recieves pointer to head in R1
# ;; Creates Nodes and imports text until EOF
# ;; Alters R0 R1 R14
# ;; Returns to whatever called it
# :ReadFile
# ;; Allocate another Node
2D20000c # LOADUI R0 12
2D0F0100 # CALLI R15 @malloc
# ;; Get another line into list
0902001F # PUSHR R1 R15
2D211100 # LOADUI R1 0x1100 ; Read from tape_01
2D0F001c # CALLI R15 @Readline
0902801F # POPR R1 R15
09000301 # SWAP R0 R1
2D0F00a0 # CALLI R15 @addline
09000301 # SWAP R0 R1
# ;; Loop if not reached EOF
2C9Effdc # JUMP.Z R14 @ReadFile
0D01001F # RET R15
# ;; Readline function
# ;; Recieves Pointer to node in R0
# ;; And Input in R1
# ;; Allocates Text segment on Heap
# ;; Sets node's pointer to Text segment
# ;; Sets R14 to True if EOF reached
# ;; Returns to whatever called it
# :Readline
# ;; Preserve registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
0902003F # PUSHR R3 R15
0902004F # PUSHR R4 R15
# ;; Initialize
09000540 # MOVE R4 R0
2D200100 # LOADUI R0 256
2D0F00bc # CALLI R15 @malloc
09000520 # MOVE R2 R0
0D000023 # FALSE R3
# :Readline_0
42100100 # FGETC ; Read a Char
# ;; Flag if reached EOF
A0100000 # CMPSKIPI.GE R0 0
0D00003E # TRUE R14
# ;; Stop if EOF
A0100000 # CMPSKIPI.GE R0 0
3C00003c # JUMP @Readline_2
# ;; Handle Backspace
A020007f # CMPSKIPI.E R0 127
3C000010 # JUMP @Readline_1
# ;; Move back 1 character if R3 > 0
A0430000 # CMPSKIPI.LE R3 0
11330001 # SUBUI R3 R3 1
# ;; Hopefully they keep typing
3C00ffdc # JUMP @Readline_0
# :Readline_1
# ;; Replace all CR with LF
A030000d # CMPSKIPI.NE R0 13
2D20000a # LOADUI R0 10
# ;; Store the Byte
05049023 # STOREX8 R0 R2 R3
# ;; Check for EOL
A030000a # CMPSKIPI.NE R0 10
3C000014 # JUMP @Readline_2
# ;; Prevent lines from exceeding 255 chars
A04300ff # CMPSKIPI.LE R3 255
3C00000c # JUMP @Readline_2
# ;; Prep for next loop
0F330001 # ADDUI R3 R3 1
3C00ffb8 # JUMP @Readline_0
# :Readline_2
# ;; Set Text pointer
23240008 # STORE32 R2 R4 8
# ;; Restore Registers
0902804F # POPR R4 R15
0902803F # POPR R3 R15
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; addline Function
# ;; Recieves pointers in R0 R1
# ;; Alters R0 if NULL
# ;; Appends nodes together
# ;; Returns to whatever called it
# :addline
# ;; Preserve Registers
0902002F # PUSHR R2 R15
0902001F # PUSHR R1 R15
0902000F # PUSHR R0 R15
# ;; Handle if Head is NULL
2CA00010 # JUMP.NZ R0 @addline_0
0902800F # POPR R0 R15
0902001F # PUSHR R1 R15
3C000020 # JUMP @addline_2
# :addline_0
# ;; Handle if Head->next is NULL
18200000 # LOAD32 R2 R0 0
2CA20010 # JUMP.NZ R2 @addline_1
# ;; Set head->next = p
23100000 # STORE32 R1 R0 0
# ;; Set p->prev = head
23010004 # STORE32 R0 R1 4
3C00000c # JUMP @addline_2
# :addline_1
# ;; Handle case of Head->next not being NULL
18000000 # LOAD32 R0 R0 0
2D0Fffcc # CALLI R15 @addline
# :addline_2
# ;; Restore registers
0902800F # POPR R0 R15
0902801F # POPR R1 R15
0902802F # POPR R2 R15
0D01001F # RET R15
# ;; Primative malloc function
# ;; Recieves number of bytes to allocate in R0
# ;; Returns pointer to block of that size in R0
# ;; Returns to whatever called it
# :malloc
# ;; Preserve registers
0902001F # PUSHR R1 R15
# ;; Get current malloc pointer
2E010020 # LOADR R1 @malloc_pointer
# ;; Deal with special case
A0310000 # CMPSKIPI.NE R1 0 ; If Zero set to our start of heap space
2D214000 # LOADUI R1 0x4000
# ;; update malloc pointer
09000301 # SWAP R0 R1
05000101 # ADD R1 R0 R1
2F01000c # STORER R1 @malloc_pointer
# ;; Done
# ;; Restore registers
0902801F # POPR R1 R15
0D01001F # RET R15
# ;; Our static value for malloc pointer
# :malloc_pointer
00000000 # NOP
# ;; Editor Loop
# ;; Provides user interaction
# ;; Requires R13 to be pointer to Head
# ;; Internally loops
# ;; Returns nothing
# :EditorLoop
0D000021 # FALSE R1 ; Read from tty
42100100 # FGETC ; Read a Char
# ;; Quit if q
A0300071 # CMPSKIPI.NE R0 113
0D01001F # RET R15
# ;; Print if p
1FE00070 # CMPUI R14 R0 112
2C6E0014 # JUMP.NE R14 @EditorLoop_0
180D0008 # LOAD32 R0 R13 8
0D000021 # FALSE R1
2D0F0118 # CALLI R15 @PrintLine
3C00ffdc # JUMP @EditorLoop
# :EditorLoop_0
# ;; Move forward if f
1FE00066 # CMPUI R14 R0 102
2C6E0014 # JUMP.NE R14 @EditorLoop_1
180D0000 # LOAD32 R0 R13 0 ; Load head->next
# ;; If head->next isn't null make it the new head
A0200000 # CMPSKIPI.E R0 0
090005D0 # MOVE R13 R0
3C00ffc4 # JUMP @EditorLoop
# :EditorLoop_1
# ;; Move backward if b
1FE00062 # CMPUI R14 R0 98
2C6E0014 # JUMP.NE R14 @EditorLoop_2
180D0004 # LOAD32 R0 R13 4 ; Load head->prev
# ;; If head->prev isn't null make it the new head
A0200000 # CMPSKIPI.E R0 0
090005D0 # MOVE R13 R0
3C00ffac # JUMP @EditorLoop
# :EditorLoop_2
# ;; Edit Line if e
1FE00065 # CMPUI R14 R0 101
2C6E0014 # JUMP.NE R14 @EditorLoop_3
# ;; Change Head's Text
0900040D # COPY R0 R13
0D000021 # FALSE R1 ; Read from tty
2D0Ffe98 # CALLI R15 @Readline
3C00ff94 # JUMP @EditorLoop
# :EditorLoop_3
# ;; Writeout to tape_02 if w
1FE00077 # CMPUI R14 R0 119
2C6E0028 # JUMP.NE R14 @EditorLoop_4
# ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE
0900040D # COPY R0 R13
2D211101 # LOADUI R1 0x1101
2D0F0058 # CALLI R15 @GetRoot
2D0F0074 # CALLI R15 @PrintAll
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02
42100002 # FCLOSE
3C00ff68 # JUMP @EditorLoop
# :EditorLoop_4
# ;; Append node if a
1FE00061 # CMPUI R14 R0 97
2C6E0010 # JUMP.NE R14 @EditorLoop_5
0900040D # COPY R0 R13
2D0F00dc # CALLI R15 @AppendLine
3C00ff54 # JUMP @EditorLoop
# :EditorLoop_5
# ;; Insert node if i
1FE00069 # CMPUI R14 R0 105
2C6E0010 # JUMP.NE R14 @EditorLoop_6
0900040D # COPY R0 R13
2D0F0108 # CALLI R15 @InsertLine
3C00ff40 # JUMP @EditorLoop
# :EditorLoop_6
# ;; Delete node if d
1FE00064 # CMPUI R14 R0 100
2C6E0014 # JUMP.NE R14 @EditorLoop_7
0900040D # COPY R0 R13
2D0F0134 # CALLI R15 @RemoveLine
090005D0 # MOVE R13 R0
3C00ff28 # JUMP @EditorLoop
# :EditorLoop_7
3C00ff24 # JUMP @EditorLoop
# ;; GetRoot function
# ;; Walks backwards through nodes until beginning
# ;; Recieves node pointer in R0 and Returns result in R0
# ;; Returns to whatever called it
# :GetRoot
# ;; Preserve registers
0902001F # PUSHR R1 R15
# :GetRoot_0
# ;; Get Head->Prev
18100004 # LOAD32 R1 R0 4
A0310000 # CMPSKIPI.NE R1 0
3C00000c # JUMP @GetRoot_1
09000501 # MOVE R0 R1
3C00fff0 # JUMP @GetRoot_0
# :GetRoot_1
# ;; Restore registers
0902801F # POPR R1 R15
0D01001F # RET R15
# ;; Printall Function
# ;; Prints all lines to Interface in R1
# ;; Starting at node in R0
# ;; Does not alter registers
# ;; Returns to whatever called it
# :PrintAll
# ;; Preserve registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
# :PrintAll_0
18200000 # LOAD32 R2 R0 0 ; Store Head->Next in R2
18000008 # LOAD32 R0 R0 8 ; Set R0 to Head->Text
2D0F0024 # CALLI R15 @PrintLine ; Prints Head->Text
A0320000 # CMPSKIPI.NE R2 0 ; If Head->Next is NULL
3C00000c # JUMP @PrintAll_1 ; Stop Looping
09000502 # MOVE R0 R2 ; Otherwise Move to Next Node
3C00ffe8 # JUMP @PrintAll_0 ; And Loop
# :PrintAll_1
# ;; Restore registers
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; Printline function
# ;; Recieves a string pointer in R0
# ;; Prints string interface specified in R1
# ;; Does not alter registers
# ;; Returns to whatever called it
# :PrintLine
# ;; Preserve registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
0902003F # PUSHR R3 R15
# ;; Initialize
09000520 # MOVE R2 R0
0D000023 # FALSE R3
# ;; Deal with NULL Pointer
A0320000 # CMPSKIPI.NE R2 0
3C00001c # JUMP @PrintLine_1
# :PrintLine_0
0503A023 # LOADXU8 R0 R2 R3 ; Load char from string
# ;; Don't print NULLs
A0300000 # CMPSKIPI.NE R0 0
3C000010 # JUMP @PrintLine_1
42100200 # FPUTC
# ; Print the char
0F330001 # ADDUI R3 R3 1 ; Prep for next loop
3C00ffec # JUMP @PrintLine_0
# :PrintLine_1
# ;; Restore registers
0902803F # POPR R3 R15
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; AppendLine Function
# ;; Recieves a Node in R0
# ;; Creates a new Node and appends it
# ;; Does not alter registers
# ;; Returns to whatever calls it
# :AppendLine
# ;; Preserve registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
# ;; Initialize
09000510 # MOVE R1 R0
# ;; Allocate another Node
2D20000c # LOADUI R0 12
2D0Ffe40 # CALLI R15 @malloc
# ;; Check if head->Next is null
18210000 # LOAD32 R2 R1 0
A0220000 # CMPSKIPI.E R2 0 ; If head->Next is something
23020004 # STORE32 R0 R2 4 ; Set head->next->prev to p
# ;; Setup p and head
23200000 # STORE32 R2 R0 0 ; p->next = head->next
23100004 # STORE32 R1 R0 4 ; p->prev = head
23010000 # STORE32 R0 R1 0 ; head->next = p
# ;; Restore Registers
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; InsertLine Function
# ;; Recieves a Node in R0
# ;; Creates a new Node and prepends it
# ;; Does not alter registers
# ;; Returns to whatever called it
# :InsertLine
# ;; Preserve Registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
# ;; Initialize
09000510 # MOVE R1 R0
# ;; Allocate another Node
2D20000c # LOADUI R0 12
2D0Ffe00 # CALLI R15 @malloc
# ;; Check if Head->Prev is Null
18210004 # LOAD32 R2 R1 4
A0220000 # CMPSKIPI.E R2 0 ; If head->prev is something
23020000 # STORE32 R0 R2 0 ; Set head->prev->next to p
# ;; Setup p and head
23200004 # STORE32 R2 R0 4 ; p->prev = head->prev
23100000 # STORE32 R1 R0 0 ; p->next = head
23010004 # STORE32 R0 R1 4 ; head->prev = p
# ;; Restore Registers
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; RemoveLine Function
# ;; Recieves Node in R0
# ;; Returns replacement node in R0
# ;; Returns to whatever called it
# :RemoveLine
# ;; Preserve Registers
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
# ;; Initialize
09000510 # MOVE R1 R0
18010004 # LOAD32 R0 R1 4 ; put p->prev in R0
18210000 # LOAD32 R2 R1 0 ; put p->next in R2
# ;; Keep links
A0200000 # CMPSKIPI.E R0 0 ; If p->prev is not null
23200000 # STORE32 R2 R0 0 ; p->prev->next = p->next
A0220000 # CMPSKIPI.E R2 0 ; If p->next is not null
23020004 # STORE32 R0 R2 4 ; p->next->prev = p->prev
# ;; Attempt to save what is left of the list
A0300000 # CMPSKIPI.NE R0 0 ; If p->prev is null
09000502 # MOVE R0 R2 ; return p->next
# ;; Restore Registers
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0D01001F # RET R15
# ;; Where our stack begins
# :stack