Wrote the bare metal Text editor SET in Assembly
This commit is contained in:
parent
cd1816c9b1
commit
c9d45a13b4
|
@ -0,0 +1,416 @@
|
|||
# :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 # CMPSKIP.GE R0 0
|
||||
0D00003E # TRUE R14
|
||||
# ;; Stop if EOF
|
||||
A0100000 # CMPSKIP.GE R0 0
|
||||
3C00003c # JUMP @Readline_2
|
||||
# ;; Handle Backspace
|
||||
A020007f # CMPSKIP.E R0 127
|
||||
3C000010 # JUMP @Readline_1
|
||||
# ;; Move back 1 character if R3 > 0
|
||||
A0430000 # CMPSKIP.LE R3 0
|
||||
11330001 # SUBUI R3 R3 1
|
||||
# ;; Hopefully they keep typing
|
||||
3C00ffdc # JUMP @Readline_0
|
||||
# :Readline_1
|
||||
# ;; Replace all CR with LF
|
||||
A030000d # CMPSKIP.NE R0 13
|
||||
2D20000a # LOADUI R0 10
|
||||
# ;; Store the Byte
|
||||
05049023 # STOREX8 R0 R2 R3
|
||||
# ;; Check for EOL
|
||||
A030000a # CMPSKIP.NE R0 10
|
||||
3C000014 # JUMP @Readline_2
|
||||
# ;; Prevent lines from exceeding 255 chars
|
||||
A04300ff # CMPSKIP.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 # CMPSKIP.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 # CMPSKIP.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 # CMPSKIP.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 # CMPSKIP.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 # CMPSKIP.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 # CMPSKIP.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 # CMPSKIP.NE R2 0
|
||||
3C00001c # JUMP @PrintLine_1
|
||||
# :PrintLine_0
|
||||
0503A023 # LOADXU8 R0 R2 R3 ; Load char from string
|
||||
# ;; Don't print NULLs
|
||||
A0300000 # CMPSKIP.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 # CMPSKIP.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 # CMPSKIP.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 # CMPSKIP.E R0 0 ; If p->prev is not null
|
||||
23200000 # STORE32 R2 R0 0 ; p->prev->next = p->next
|
||||
A0220000 # CMPSKIP.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 # CMPSKIP.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
|
|
@ -0,0 +1,427 @@
|
|||
:start
|
||||
2D2F $stack # 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
|
||||
2D0F @ReadFile # 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
|
||||
2D0F @EditorLoop # 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
|
||||
2D0F @malloc # CALLI R15 @malloc
|
||||
# ;; Get another line into list
|
||||
0902001F # PUSHR R1 R15
|
||||
2D211100 # LOADUI R1 0x1100 ; Read from tape_01
|
||||
2D0F @Readline # CALLI R15 @Readline
|
||||
0902801F # POPR R1 R15
|
||||
09000301 # SWAP R0 R1
|
||||
2D0F @addline # CALLI R15 @addline
|
||||
09000301 # SWAP R0 R1
|
||||
# ;; Loop if not reached EOF
|
||||
2C9E @ReadFile # 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
|
||||
2D0F @malloc # CALLI R15 @malloc
|
||||
09000520 # MOVE R2 R0
|
||||
0D000023 # FALSE R3
|
||||
:Readline_0
|
||||
42100100 # FGETC ; Read a Char
|
||||
# ;; Flag if reached EOF
|
||||
A0100000 # CMPSKIP.GE R0 0
|
||||
0D00003E # TRUE R14
|
||||
# ;; Stop if EOF
|
||||
A0100000 # CMPSKIP.GE R0 0
|
||||
3C00 @Readline_2 # JUMP @Readline_2
|
||||
# ;; Handle Backspace
|
||||
A020007f # CMPSKIP.E R0 127
|
||||
3C00 @Readline_1 # JUMP @Readline_1
|
||||
# ;; Move back 1 character if R3 > 0
|
||||
A0430000 # CMPSKIP.LE R3 0
|
||||
11330001 # SUBUI R3 R3 1
|
||||
# ;; Hopefully they keep typing
|
||||
3C00 @Readline_0 # JUMP @Readline_0
|
||||
:Readline_1
|
||||
# ;; Replace all CR with LF
|
||||
A030000d # CMPSKIP.NE R0 13
|
||||
2D20000a # LOADUI R0 10
|
||||
# ;; Store the Byte
|
||||
05049023 # STOREX8 R0 R2 R3
|
||||
# ;; Check for EOL
|
||||
A030000a # CMPSKIP.NE R0 10
|
||||
3C00 @Readline_2 # JUMP @Readline_2
|
||||
# ;; Prevent lines from exceeding 255 chars
|
||||
A04300ff # CMPSKIP.LE R3 255
|
||||
3C00 @Readline_2 # JUMP @Readline_2
|
||||
# ;; Prep for next loop
|
||||
0F330001 # ADDUI R3 R3 1
|
||||
3C00 @Readline_0 # 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
|
||||
2CA0 @addline_0 # JUMP.NZ R0 @addline_0
|
||||
0902800F # POPR R0 R15
|
||||
0902001F # PUSHR R1 R15
|
||||
3C00 @addline_2 # JUMP @addline_2
|
||||
:addline_0
|
||||
# ;; Handle if Head->next is NULL
|
||||
18200000 # LOAD32 R2 R0 0
|
||||
2CA2 @addline_1 # JUMP.NZ R2 @addline_1
|
||||
# ;; Set head->next = p
|
||||
23100000 # STORE32 R1 R0 0
|
||||
# ;; Set p->prev = head
|
||||
23010004 # STORE32 R0 R1 4
|
||||
3C00 @addline_2 # JUMP @addline_2
|
||||
:addline_1
|
||||
# ;; Handle case of Head->next not being NULL
|
||||
18000000 # LOAD32 R0 R0 0
|
||||
2D0F @addline # 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
|
||||
2E01 @malloc_pointer # LOADR R1 @malloc_pointer
|
||||
# ;; Deal with special case
|
||||
A0310000 # CMPSKIP.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
|
||||
2F01 @malloc_pointer # 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 # CMPSKIP.NE R0 113
|
||||
0D01001F # RET R15
|
||||
# ;; Print if p
|
||||
1FE00070 # CMPUI R14 R0 112
|
||||
2C6E @EditorLoop_0 # JUMP.NE R14 @EditorLoop_0
|
||||
180D0008 # LOAD32 R0 R13 8
|
||||
0D000021 # FALSE R1
|
||||
2D0F @PrintLine # CALLI R15 @PrintLine
|
||||
3C00 @EditorLoop # JUMP @EditorLoop
|
||||
:EditorLoop_0
|
||||
# ;; Move forward if f
|
||||
1FE00066 # CMPUI R14 R0 102
|
||||
2C6E @EditorLoop_1 # 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 # CMPSKIP.E R0 0
|
||||
090005D0 # MOVE R13 R0
|
||||
3C00 @EditorLoop # JUMP @EditorLoop
|
||||
:EditorLoop_1
|
||||
# ;; Move backward if b
|
||||
1FE00062 # CMPUI R14 R0 98
|
||||
2C6E @EditorLoop_2 # 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 # CMPSKIP.E R0 0
|
||||
090005D0 # MOVE R13 R0
|
||||
3C00 @EditorLoop # JUMP @EditorLoop
|
||||
:EditorLoop_2
|
||||
# ;; Edit Line if e
|
||||
1FE00065 # CMPUI R14 R0 101
|
||||
2C6E @EditorLoop_3 # JUMP.NE R14 @EditorLoop_3
|
||||
# ;; Change Head's Text
|
||||
0900040D # COPY R0 R13
|
||||
0D000021 # FALSE R1 ; Read from tty
|
||||
2D0F @Readline # CALLI R15 @Readline
|
||||
3C00 @EditorLoop # JUMP @EditorLoop
|
||||
:EditorLoop_3
|
||||
# ;; Writeout to tape_02 if w
|
||||
1FE00077 # CMPUI R14 R0 119
|
||||
2C6E @EditorLoop_4 # JUMP.NE R14 @EditorLoop_4
|
||||
# ;; Prep TAPE_02
|
||||
2D201101 # LOADUI R0 0x1101
|
||||
42100001 # FOPEN_WRITE
|
||||
0900040D # COPY R0 R13
|
||||
2D211101 # LOADUI R1 0x1101
|
||||
2D0F @GetRoot # CALLI R15 @GetRoot
|
||||
2D0F @PrintAll # CALLI R15 @PrintAll
|
||||
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02
|
||||
42100002 # FCLOSE
|
||||
3C00 @EditorLoop # JUMP @EditorLoop
|
||||
:EditorLoop_4
|
||||
# ;; Append node if a
|
||||
1FE00061 # CMPUI R14 R0 97
|
||||
2C6E @EditorLoop_5 # JUMP.NE R14 @EditorLoop_5
|
||||
0900040D # COPY R0 R13
|
||||
2D0F @AppendLine # CALLI R15 @AppendLine
|
||||
3C00 @EditorLoop # JUMP @EditorLoop
|
||||
:EditorLoop_5
|
||||
# ;; Insert node if i
|
||||
1FE00069 # CMPUI R14 R0 105
|
||||
2C6E @EditorLoop_6 # JUMP.NE R14 @EditorLoop_6
|
||||
0900040D # COPY R0 R13
|
||||
2D0F @InsertLine # CALLI R15 @InsertLine
|
||||
3C00 @EditorLoop # JUMP @EditorLoop
|
||||
:EditorLoop_6
|
||||
# ;; Delete node if d
|
||||
1FE00064 # CMPUI R14 R0 100
|
||||
2C6E @EditorLoop_7 # JUMP.NE R14 @EditorLoop_7
|
||||
0900040D # COPY R0 R13
|
||||
2D0F @RemoveLine # CALLI R15 @RemoveLine
|
||||
090005D0 # MOVE R13 R0
|
||||
3C00 @EditorLoop # JUMP @EditorLoop
|
||||
:EditorLoop_7
|
||||
3C00 @EditorLoop # 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 # CMPSKIP.NE R1 0
|
||||
3C00 @GetRoot_1 # JUMP @GetRoot_1
|
||||
09000501 # MOVE R0 R1
|
||||
3C00 @GetRoot_0 # 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
|
||||
2D0F @PrintLine # CALLI R15 @PrintLine ; Prints Head->Text
|
||||
A0320000 # CMPSKIP.NE R2 0 ; If Head->Next is NULL
|
||||
3C00 @PrintAll_1 # JUMP @PrintAll_1 ; Stop Looping
|
||||
09000502 # MOVE R0 R2 ; Otherwise Move to Next Node
|
||||
3C00 @PrintAll_0 # 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 # CMPSKIP.NE R2 0
|
||||
3C00 @PrintLine_1 # JUMP @PrintLine_1
|
||||
:PrintLine_0
|
||||
0503A023 # LOADXU8 R0 R2 R3 ; Load char from string
|
||||
# ;; Don't print NULLs
|
||||
A0300000 # CMPSKIP.NE R0 0
|
||||
3C00 @PrintLine_1 # JUMP @PrintLine_1
|
||||
42100200 # FPUTC
|
||||
# ; Print the char
|
||||
0F330001 # ADDUI R3 R3 1 ; Prep for next loop
|
||||
3C00 @PrintLine_0 # 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
|
||||
2D0F @malloc # CALLI R15 @malloc
|
||||
# ;; Check if head->Next is null
|
||||
18210000 # LOAD32 R2 R1 0
|
||||
A0220000 # CMPSKIP.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
|
||||
2D0F @malloc # CALLI R15 @malloc
|
||||
# ;; Check if Head->Prev is Null
|
||||
18210004 # LOAD32 R2 R1 4
|
||||
A0220000 # CMPSKIP.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 # CMPSKIP.E R0 0 ; If p->prev is not null
|
||||
23200000 # STORE32 R2 R0 0 ; p->prev->next = p->next
|
||||
A0220000 # CMPSKIP.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 # CMPSKIP.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
|
|
@ -0,0 +1,467 @@
|
|||
:start
|
||||
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
|
||||
LOADUI R0 0x1100
|
||||
FOPEN_READ
|
||||
|
||||
;; Prepare to Read File
|
||||
FALSE R14
|
||||
FALSE R1
|
||||
CALLI R15 @ReadFile
|
||||
|
||||
;; Done reading File
|
||||
LOADUI R0 0x1100 ; Close TAPE_01
|
||||
FCLOSE
|
||||
|
||||
;; Enter Editor Loop
|
||||
MOVE R13 R1 ; Set R13 to Head
|
||||
CALLI R15 @EditorLoop
|
||||
|
||||
;; And We are Done
|
||||
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
|
||||
LOADUI R0 12
|
||||
CALLI R15 @malloc
|
||||
;; Get another line into list
|
||||
PUSHR R1 R15
|
||||
LOADUI R1 0x1100 ; Read from tape_01
|
||||
CALLI R15 @Readline
|
||||
POPR R1 R15
|
||||
SWAP R0 R1
|
||||
CALLI R15 @addline
|
||||
SWAP R0 R1
|
||||
;; Loop if not reached EOF
|
||||
JUMP.Z R14 @ReadFile
|
||||
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
|
||||
PUSHR R0 R15
|
||||
PUSHR R1 R15
|
||||
PUSHR R2 R15
|
||||
PUSHR R3 R15
|
||||
PUSHR R4 R15
|
||||
;; Initialize
|
||||
MOVE R4 R0
|
||||
LOADUI R0 256
|
||||
CALLI R15 @malloc
|
||||
MOVE R2 R0
|
||||
FALSE R3
|
||||
:Readline_0
|
||||
FGETC ; Read a Char
|
||||
|
||||
;; Flag if reached EOF
|
||||
CMPSKIP.GE R0 0
|
||||
TRUE R14
|
||||
|
||||
;; Stop if EOF
|
||||
CMPSKIP.GE R0 0
|
||||
JUMP @Readline_2
|
||||
|
||||
;; Handle Backspace
|
||||
CMPSKIP.E R0 127
|
||||
JUMP @Readline_1
|
||||
|
||||
;; Move back 1 character if R3 > 0
|
||||
CMPSKIP.LE R3 0
|
||||
SUBUI R3 R3 1
|
||||
|
||||
;; Hopefully they keep typing
|
||||
JUMP @Readline_0
|
||||
|
||||
:Readline_1
|
||||
;; Replace all CR with LF
|
||||
CMPSKIP.NE R0 13
|
||||
LOADUI R0 10
|
||||
|
||||
;; Store the Byte
|
||||
STOREX8 R0 R2 R3
|
||||
|
||||
;; Check for EOL
|
||||
CMPSKIP.NE R0 10
|
||||
JUMP @Readline_2
|
||||
|
||||
;; Prevent lines from exceeding 255 chars
|
||||
CMPSKIP.LE R3 255
|
||||
JUMP @Readline_2
|
||||
|
||||
;; Prep for next loop
|
||||
ADDUI R3 R3 1
|
||||
JUMP @Readline_0
|
||||
|
||||
:Readline_2
|
||||
;; Set Text pointer
|
||||
STORE32 R2 R4 8
|
||||
;; Restore Registers
|
||||
POPR R4 R15
|
||||
POPR R3 R15
|
||||
POPR R2 R15
|
||||
POPR R1 R15
|
||||
POPR R0 R15
|
||||
RET R15
|
||||
|
||||
;; addline Function
|
||||
;; Recieves pointers in R0 R1
|
||||
;; Alters R0 if NULL
|
||||
;; Appends nodes together
|
||||
;; Returns to whatever called it
|
||||
:addline
|
||||
;; Preserve Registers
|
||||
PUSHR R2 R15
|
||||
PUSHR R1 R15
|
||||
PUSHR R0 R15
|
||||
|
||||
;; Handle if Head is NULL
|
||||
JUMP.NZ R0 @addline_0
|
||||
POPR R0 R15
|
||||
PUSHR R1 R15
|
||||
JUMP @addline_2
|
||||
|
||||
:addline_0
|
||||
;; Handle if Head->next is NULL
|
||||
LOAD32 R2 R0 0
|
||||
JUMP.NZ R2 @addline_1
|
||||
;; Set head->next = p
|
||||
STORE32 R1 R0 0
|
||||
;; Set p->prev = head
|
||||
STORE32 R0 R1 4
|
||||
JUMP @addline_2
|
||||
|
||||
:addline_1
|
||||
;; Handle case of Head->next not being NULL
|
||||
LOAD32 R0 R0 0
|
||||
CALLI R15 @addline
|
||||
|
||||
:addline_2
|
||||
;; Restore registers
|
||||
POPR R0 R15
|
||||
POPR R1 R15
|
||||
POPR R2 R15
|
||||
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
|
||||
PUSHR R1 R15
|
||||
;; Get current malloc pointer
|
||||
LOADR R1 @malloc_pointer
|
||||
;; Deal with special case
|
||||
CMPSKIP.NE R1 0 ; If Zero set to our start of heap space
|
||||
LOADUI R1 0x4000
|
||||
|
||||
;; update malloc pointer
|
||||
SWAP R0 R1
|
||||
ADD R1 R0 R1
|
||||
STORER R1 @malloc_pointer
|
||||
|
||||
;; Done
|
||||
;; Restore registers
|
||||
POPR R1 R15
|
||||
RET R15
|
||||
;; Our static value for malloc pointer
|
||||
:malloc_pointer
|
||||
NOP
|
||||
|
||||
;; Editor Loop
|
||||
;; Provides user interaction
|
||||
;; Requires R13 to be pointer to Head
|
||||
;; Internally loops
|
||||
;; Returns nothing
|
||||
:EditorLoop
|
||||
FALSE R1 ; Read from tty
|
||||
FGETC ; Read a Char
|
||||
|
||||
;; Quit if q
|
||||
CMPSKIP.NE R0 113
|
||||
RET R15
|
||||
|
||||
;; Print if p
|
||||
CMPUI R14 R0 112
|
||||
JUMP.NE R14 @EditorLoop_0
|
||||
LOAD32 R0 R13 8
|
||||
FALSE R1
|
||||
CALLI R15 @PrintLine
|
||||
JUMP @EditorLoop
|
||||
|
||||
:EditorLoop_0
|
||||
;; Move forward if f
|
||||
CMPUI R14 R0 102
|
||||
JUMP.NE R14 @EditorLoop_1
|
||||
LOAD32 R0 R13 0 ; Load head->next
|
||||
|
||||
;; If head->next isn't null make it the new head
|
||||
CMPSKIP.E R0 0
|
||||
MOVE R13 R0
|
||||
JUMP @EditorLoop
|
||||
|
||||
:EditorLoop_1
|
||||
;; Move backward if b
|
||||
CMPUI R14 R0 98
|
||||
JUMP.NE R14 @EditorLoop_2
|
||||
LOAD32 R0 R13 4 ; Load head->prev
|
||||
|
||||
;; If head->prev isn't null make it the new head
|
||||
CMPSKIP.E R0 0
|
||||
MOVE R13 R0
|
||||
JUMP @EditorLoop
|
||||
|
||||
:EditorLoop_2
|
||||
;; Edit Line if e
|
||||
CMPUI R14 R0 101
|
||||
JUMP.NE R14 @EditorLoop_3
|
||||
|
||||
;; Change Head's Text
|
||||
COPY R0 R13
|
||||
FALSE R1 ; Read from tty
|
||||
CALLI R15 @Readline
|
||||
|
||||
JUMP @EditorLoop
|
||||
|
||||
:EditorLoop_3
|
||||
;; Writeout to tape_02 if w
|
||||
CMPUI R14 R0 119
|
||||
JUMP.NE R14 @EditorLoop_4
|
||||
|
||||
;; Prep TAPE_02
|
||||
LOADUI R0 0x1101
|
||||
FOPEN_WRITE
|
||||
|
||||
COPY R0 R13
|
||||
LOADUI R1 0x1101
|
||||
CALLI R15 @GetRoot
|
||||
CALLI R15 @PrintAll
|
||||
|
||||
LOADUI R0 0x1101 ; Close TAPE_02
|
||||
FCLOSE
|
||||
JUMP @EditorLoop
|
||||
|
||||
:EditorLoop_4
|
||||
;; Append node if a
|
||||
CMPUI R14 R0 97
|
||||
JUMP.NE R14 @EditorLoop_5
|
||||
COPY R0 R13
|
||||
CALLI R15 @AppendLine
|
||||
JUMP @EditorLoop
|
||||
|
||||
:EditorLoop_5
|
||||
;; Insert node if i
|
||||
CMPUI R14 R0 105
|
||||
JUMP.NE R14 @EditorLoop_6
|
||||
COPY R0 R13
|
||||
CALLI R15 @InsertLine
|
||||
JUMP @EditorLoop
|
||||
|
||||
:EditorLoop_6
|
||||
;; Delete node if d
|
||||
CMPUI R14 R0 100
|
||||
JUMP.NE R14 @EditorLoop_7
|
||||
COPY R0 R13
|
||||
CALLI R15 @RemoveLine
|
||||
MOVE R13 R0
|
||||
JUMP @EditorLoop
|
||||
|
||||
:EditorLoop_7
|
||||
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
|
||||
PUSHR R1 R15
|
||||
:GetRoot_0
|
||||
;; Get Head->Prev
|
||||
LOAD32 R1 R0 4
|
||||
|
||||
CMPSKIP.NE R1 0
|
||||
JUMP @GetRoot_1
|
||||
|
||||
MOVE R0 R1
|
||||
JUMP @GetRoot_0
|
||||
|
||||
:GetRoot_1
|
||||
;; Restore registers
|
||||
POPR R1 R15
|
||||
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
|
||||
PUSHR R0 R15
|
||||
PUSHR R1 R15
|
||||
PUSHR R2 R15
|
||||
:PrintAll_0
|
||||
LOAD32 R2 R0 0 ; Store Head->Next in R2
|
||||
LOAD32 R0 R0 8 ; Set R0 to Head->Text
|
||||
CALLI R15 @PrintLine ; Prints Head->Text
|
||||
CMPSKIP.NE R2 0 ; If Head->Next is NULL
|
||||
JUMP @PrintAll_1 ; Stop Looping
|
||||
MOVE R0 R2 ; Otherwise Move to Next Node
|
||||
JUMP @PrintAll_0 ; And Loop
|
||||
:PrintAll_1
|
||||
;; Restore registers
|
||||
POPR R2 R15
|
||||
POPR R1 R15
|
||||
POPR R0 R15
|
||||
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
|
||||
PUSHR R0 R15
|
||||
PUSHR R1 R15
|
||||
PUSHR R2 R15
|
||||
PUSHR R3 R15
|
||||
;; Initialize
|
||||
MOVE R2 R0
|
||||
FALSE R3
|
||||
;; Deal with NULL Pointer
|
||||
CMPSKIP.NE R2 0
|
||||
JUMP @PrintLine_1
|
||||
:PrintLine_0
|
||||
LOADXU8 R0 R2 R3 ; Load char from string
|
||||
;; Don't print NULLs
|
||||
CMPSKIP.NE R0 0
|
||||
JUMP @PrintLine_1
|
||||
|
||||
FPUTC ; Print the char
|
||||
ADDUI R3 R3 1 ; Prep for next loop
|
||||
JUMP @PrintLine_0
|
||||
|
||||
:PrintLine_1
|
||||
;; Restore registers
|
||||
POPR R3 R15
|
||||
POPR R2 R15
|
||||
POPR R1 R15
|
||||
POPR R0 R15
|
||||
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
|
||||
PUSHR R0 R15
|
||||
PUSHR R1 R15
|
||||
PUSHR R2 R15
|
||||
;; Initialize
|
||||
MOVE R1 R0
|
||||
;; Allocate another Node
|
||||
LOADUI R0 12
|
||||
CALLI R15 @malloc
|
||||
|
||||
;; Check if head->Next is null
|
||||
LOAD32 R2 R1 0
|
||||
CMPSKIP.E R2 0 ; If head->Next is something
|
||||
STORE32 R0 R2 4 ; Set head->next->prev to p
|
||||
|
||||
;; Setup p and head
|
||||
STORE32 R2 R0 0 ; p->next = head->next
|
||||
STORE32 R1 R0 4 ; p->prev = head
|
||||
STORE32 R0 R1 0 ; head->next = p
|
||||
|
||||
;; Restore Registers
|
||||
POPR R2 R15
|
||||
POPR R1 R15
|
||||
POPR R0 R15
|
||||
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
|
||||
PUSHR R0 R15
|
||||
PUSHR R1 R15
|
||||
PUSHR R2 R15
|
||||
;; Initialize
|
||||
MOVE R1 R0
|
||||
;; Allocate another Node
|
||||
LOADUI R0 12
|
||||
CALLI R15 @malloc
|
||||
|
||||
;; Check if Head->Prev is Null
|
||||
LOAD32 R2 R1 4
|
||||
CMPSKIP.E R2 0 ; If head->prev is something
|
||||
STORE32 R0 R2 0 ; Set head->prev->next to p
|
||||
|
||||
;; Setup p and head
|
||||
STORE32 R2 R0 4 ; p->prev = head->prev
|
||||
STORE32 R1 R0 0 ; p->next = head
|
||||
STORE32 R0 R1 4 ; head->prev = p
|
||||
|
||||
;; Restore Registers
|
||||
POPR R2 R15
|
||||
POPR R1 R15
|
||||
POPR R0 R15
|
||||
RET R15
|
||||
|
||||
|
||||
;; RemoveLine Function
|
||||
;; Recieves Node in R0
|
||||
;; Returns replacement node in R0
|
||||
;; Returns to whatever called it
|
||||
:RemoveLine
|
||||
;; Preserve Registers
|
||||
PUSHR R1 R15
|
||||
PUSHR R2 R15
|
||||
;; Initialize
|
||||
MOVE R1 R0
|
||||
LOAD32 R0 R1 4 ; put p->prev in R0
|
||||
LOAD32 R2 R1 0 ; put p->next in R2
|
||||
|
||||
;; Keep links
|
||||
CMPSKIP.E R0 0 ; If p->prev is not null
|
||||
STORE32 R2 R0 0 ; p->prev->next = p->next
|
||||
|
||||
CMPSKIP.E R2 0 ; If p->next is not null
|
||||
STORE32 R0 R2 4 ; p->next->prev = p->prev
|
||||
|
||||
;; Attempt to save what is left of the list
|
||||
CMPSKIP.NE R0 0 ; If p->prev is null
|
||||
MOVE R0 R2 ; return p->next
|
||||
|
||||
;; Restore Registers
|
||||
POPR R2 R15
|
||||
POPR R1 R15
|
||||
RET R15
|
||||
|
||||
;; Where our stack begins
|
||||
:stack
|
Loading…
Reference in New Issue