mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Pep/8 is a toy assembly language used in some universities for teaching the basics of assembly and low-level programming. Signed-off-by: Lucas Bajolet <lucas.bajolet@gmail.com>
		
			
				
	
	
		
			676 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			676 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
; Linked list of integers API
 | 
						|
;
 | 
						|
; Contains the basis of the structure and a
 | 
						|
; variety of available functions to call on it.
 | 
						|
;
 | 
						|
; Calling conventions:
 | 
						|
;
 | 
						|
;   - When the number of arguments is <= 2, the fastcall convention will be used:
 | 
						|
;   Arguments will be passed by registers, no assumption is made concerning the
 | 
						|
;   state of the registers during execution, they will need to be saved.
 | 
						|
;
 | 
						|
;   - When the number of arguments exceeds 2, the cdecl convention will be used:
 | 
						|
;   Arguments will be passed on the stack, no assumption is made concerning the
 | 
						|
;   state of the registers during execution, they will need to be saved.
 | 
						|
 | 
						|
; Simple test program, do no include when using the library
 | 
						|
main:       SUBSP   4, i
 | 
						|
            DECI    mnelmt, s
 | 
						|
            CALL    newlst
 | 
						|
            LDX     mnlst, s
 | 
						|
            CALL    lstgetst
 | 
						|
            LDX     mnlst, s
 | 
						|
            CALL    lstsetst
 | 
						|
            LDX     mnlst, s
 | 
						|
            CALL    lstgetst
 | 
						|
            LDX     mnlst, s
 | 
						|
            CALL    shftest
 | 
						|
            LDX     mnlst, s
 | 
						|
            CALL    ushftest
 | 
						|
            LDX     mnlst, s
 | 
						|
            CALL    shftest
 | 
						|
            ADDSP   4, i
 | 
						|
            STOP
 | 
						|
; Pointer to the list
 | 
						|
mnlst:      .EQUATE 0
 | 
						|
; Element read
 | 
						|
mnelmt:     .EQUATE 2
 | 
						|
 | 
						|
; TESTS
 | 
						|
 | 
						|
; Simple test for the get operation
 | 
						|
; Gets the first element of the list and prints it
 | 
						|
;
 | 
						|
; REQUIRES: Non-empty list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   void
 | 
						|
lstgetst:   SUBSP   2, i
 | 
						|
            LDA     0, i
 | 
						|
            CALL    lstget
 | 
						|
            STA     0, s
 | 
						|
            DECO    0, s
 | 
						|
            CHARO   '\n', i
 | 
						|
            ADDSP   2, i
 | 
						|
            RET0
 | 
						|
 | 
						|
; Test for the set operation
 | 
						|
; Sets the first element of the list to a given value
 | 
						|
; The value is read from stdin
 | 
						|
;
 | 
						|
; REQUIRES: Non-empty list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   void
 | 
						|
lstsetst:   SUBSP   6, i
 | 
						|
            STX     0, s
 | 
						|
            DECI    4, s
 | 
						|
            LDA     0, i
 | 
						|
            STA     2, s
 | 
						|
            CALL    lstset
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
 | 
						|
; Tests shift operation on a list
 | 
						|
; Gets the last element of the list and prints it
 | 
						|
;
 | 
						|
; REQUIRES: Non-empty list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   void
 | 
						|
shftest:    SUBSP   2, i
 | 
						|
            CALL    lstshft
 | 
						|
            STA     0, s
 | 
						|
            DECO    0, s
 | 
						|
            CHARO   '\n', i
 | 
						|
            ADDSP   2, i
 | 
						|
            RET0
 | 
						|
 | 
						|
; Tests unshift operation on a list
 | 
						|
; Unshifts a new element read from keyboard
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   void
 | 
						|
ushftest:   SUBSP   2, i
 | 
						|
            DECI    0, s
 | 
						|
            LDA     0, s
 | 
						|
            CALL    lstunshf
 | 
						|
            ADDSP   2, i
 | 
						|
            RET0
 | 
						|
 | 
						|
; LIBRARY
 | 
						|
 | 
						|
; Creates a new list with `element` as head
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   SP + 4: Element
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   SP + 2: Pointer to the list
 | 
						|
newlst:     LDA     lstlen, i
 | 
						|
            CALL    new
 | 
						|
            STX     2, s
 | 
						|
            CALL    newnode
 | 
						|
            SUBSP   2, i
 | 
						|
            STX     0, s
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            LDA     6, s
 | 
						|
            STA     0, sxf
 | 
						|
            LDA     0, s
 | 
						|
            LDX     lsthead, i
 | 
						|
            STA     4, sxf
 | 
						|
            ADDSP   2, i
 | 
						|
            RET0
 | 
						|
 | 
						|
; Gets a node at specified index in a list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - A: Index
 | 
						|
;   - X: Pointer to the list
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: Error code (0 if no error was produced)
 | 
						|
;   - X: Pointer to the node
 | 
						|
;
 | 
						|
; Errors:
 | 
						|
;   -1: Index < 0
 | 
						|
;   -2: Index >= list.length
 | 
						|
nodeat:     SUBSP   10, i
 | 
						|
            STA     ndaind, s
 | 
						|
            STX     ndalst, s
 | 
						|
            LDX     lsthead, i
 | 
						|
            LDA     ndalst, sxf
 | 
						|
            STA     ndanode, s
 | 
						|
            LDA     ndaind, s
 | 
						|
            CPA     0, i
 | 
						|
            LDA     0, i
 | 
						|
            STA     ndacurri, s
 | 
						|
            BRGE    ndagez
 | 
						|
            LDA     -1, i
 | 
						|
            ADDSP   10, i
 | 
						|
            RET0
 | 
						|
ndagez:     LDX     ndalst, s
 | 
						|
            CALL    listlen
 | 
						|
            STA     ndalstln, s
 | 
						|
            LDA     ndaind, s
 | 
						|
            CPA     ndalstln, s
 | 
						|
            BRLT    ndalp
 | 
						|
            LDA     -2, i
 | 
						|
            ADDSP   10, i
 | 
						|
            RET0
 | 
						|
ndalp:      LDA     ndacurri, s
 | 
						|
            CPA     ndaind, s
 | 
						|
            BREQ    ndaout
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     ndanode, sxf
 | 
						|
            STA     ndanode, s
 | 
						|
            LDA     ndacurri, s
 | 
						|
            ADDA    1, i
 | 
						|
            STA     ndacurri, s
 | 
						|
            BR      ndalp
 | 
						|
ndaout:     LDX     ndanode, s
 | 
						|
            LDA     0, i
 | 
						|
            ADDSP   10, i
 | 
						|
            RET0
 | 
						|
ndaind:     .EQUATE 0
 | 
						|
ndanode:    .EQUATE 2
 | 
						|
ndalst:     .EQUATE 4
 | 
						|
ndalstln:   .EQUATE 6
 | 
						|
ndacurri:   .EQUATE 8
 | 
						|
 | 
						|
; Length of the list passed as a parameter
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: List
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: Length
 | 
						|
listlen:    SUBSP   4, i
 | 
						|
            STX     lenode, s
 | 
						|
            LDX     lenode, sf
 | 
						|
            STX     lenode, s
 | 
						|
            LDA     0, i
 | 
						|
            STA     lencpt, s
 | 
						|
llenlp:     LDA     lenode, s
 | 
						|
            CPA     0, i
 | 
						|
            BREQ    lenout
 | 
						|
            LDA     lencpt, s
 | 
						|
            ADDA    1, i
 | 
						|
            STA     lencpt, s
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lenode, sxf
 | 
						|
            STA     lenode, s
 | 
						|
            BR      llenlp
 | 
						|
lenout:     LDA     lencpt, s
 | 
						|
            ADDSP   4, i
 | 
						|
            RET0
 | 
						|
lenode:     .EQUATE 0
 | 
						|
lencpt:     .EQUATE 2
 | 
						|
 | 
						|
; Gets an element in a list at a specified index
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - A: Index
 | 
						|
;   - X: Address of the list
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: Element value
 | 
						|
;
 | 
						|
; Error:
 | 
						|
;   If out of bounds, prints an error message and stops the program
 | 
						|
lstget:     SUBSP   2, i
 | 
						|
            STA     0, s
 | 
						|
            CALL    nodeat
 | 
						|
            CPA     0, i
 | 
						|
            BRNE    getoob
 | 
						|
            LDA     0, x
 | 
						|
            ADDSP   2, i
 | 
						|
            RET0
 | 
						|
; Out of bounds
 | 
						|
getoob:     STRO    getstrob, d
 | 
						|
            DECO    0, s
 | 
						|
            CHARO   '\n', i
 | 
						|
            STOP
 | 
						|
; String for out of bounds error
 | 
						|
getstrob:   .ASCII  "Invalid index on get, index = \x00"
 | 
						|
 | 
						|
; Sets an element in a list at a specified index to a new value
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - SP + 2: Pointer to the list
 | 
						|
;   - SP + 4: Index
 | 
						|
;   - SP + 6: Element
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: 0 if all went well, an error code otherwise (analogous to the error codes in nodeat)
 | 
						|
lstset:     CHARO   '\n', i
 | 
						|
            DECO    lstsetlp, s
 | 
						|
            CHARO   ' ', i
 | 
						|
            DECO    lstsetin, s
 | 
						|
            CHARO   ' ', i
 | 
						|
            DECO    lstsetel, s
 | 
						|
            CHARO   '\n', i
 | 
						|
            SUBSP   2, i
 | 
						|
            LDX     lstsetlp, s
 | 
						|
            LDA     lstsetin, s
 | 
						|
            CALL    nodeat
 | 
						|
            CPA     0, i
 | 
						|
            BRNE    lstsetrt
 | 
						|
            STX     lstsetnp, s
 | 
						|
            LDA     lstsetel, s
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            STA     lstsetnp, sxf
 | 
						|
            LDA     0, i
 | 
						|
lstsetrt:   ADDSP   2, i
 | 
						|
            RET0
 | 
						|
; Pointer to the list
 | 
						|
lstsetlp:   .EQUATE 4
 | 
						|
; Element to set the value at
 | 
						|
lstsetel:   .EQUATE 8
 | 
						|
; Index of the node
 | 
						|
lstsetin:   .EQUATE 6
 | 
						|
; Pointer to the node
 | 
						|
lstsetnp:   .EQUATE 0
 | 
						|
 | 
						|
; Removes the first element of the list in parameter and returns its value
 | 
						|
;
 | 
						|
; REQUIRES: Non-empty list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   ⁻ X: Pointer to the list
 | 
						|
;
 | 
						|
; Returns :
 | 
						|
;   - A: Element removed
 | 
						|
lstshft:    SUBSP   8, i
 | 
						|
            STX     lshflp, s
 | 
						|
            LDX     lsthead, i
 | 
						|
            LDA     lshflp, sxf
 | 
						|
            CPA     0, i
 | 
						|
            BREQ    shfterr
 | 
						|
            STA     lshfohd, s
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lshfohd, sxf
 | 
						|
            STA     lshfnhd, s
 | 
						|
            LDX     lsthead, i
 | 
						|
            STA     lshflp, sxf
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            LDA     lshfohd, sxf
 | 
						|
            ADDSP   8, i
 | 
						|
            RET0
 | 
						|
shfterr:    STRO    shfterrm, d
 | 
						|
            STOP
 | 
						|
; Pointer to the list
 | 
						|
lshflp:     .EQUATE 0
 | 
						|
; Pointer to the old head
 | 
						|
lshfohd:    .EQUATE 2
 | 
						|
; Old head's element
 | 
						|
lshfhdel:   .EQUATE 4
 | 
						|
; Pointer to the new head
 | 
						|
lshfnhd:    .EQUATE 6
 | 
						|
; Error message on shift
 | 
						|
shfterrm:   .ASCII "Cannot do shift on empty list.\n\x00"
 | 
						|
 | 
						|
; Inserts a new element at the beginning of a list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;   - A: Element to add to the list
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: Error code, 0 if all right, a code otherwise
 | 
						|
lstunshf:   SUBSP   8, i
 | 
						|
            STA     lunshelm, s
 | 
						|
            STX     lunslp, s
 | 
						|
            CALL    newnode
 | 
						|
            STX     lunsnhd, s
 | 
						|
            LDX     lsthead, i
 | 
						|
            LDA     lunslp, sxf
 | 
						|
            STA     lunsohd, s
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lunsohd, s
 | 
						|
            STA     lunsnhd, sxf
 | 
						|
            LDA     lunshelm, s
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            STA     lunsohd, sxf
 | 
						|
            LDX     lsthead, i
 | 
						|
            LDA     lunsnhd, s
 | 
						|
            STA     lunslp, sxf
 | 
						|
            ADDSP   8, i
 | 
						|
            RET0
 | 
						|
; Pointer to the list
 | 
						|
lunslp:     .EQUATE 0
 | 
						|
; Pointer to the old head
 | 
						|
lunsohd:    .EQUATE 2
 | 
						|
; Pointer to the new head
 | 
						|
lunsnhd:    .EQUATE 4
 | 
						|
; Element to add
 | 
						|
lunshelm:   .EQUATE 6
 | 
						|
 | 
						|
; Finds whether or not an element is present in a list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;   - A: Element to be found
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: 0 if element was not found, 1 if it was
 | 
						|
lstfnd:     SUBSP   6, i
 | 
						|
            STX     lstfndlp, s
 | 
						|
            STA     lstfndel, s
 | 
						|
            LDX     lsthead, i
 | 
						|
            LDA     lstfndlp, sxf
 | 
						|
            STA     lstfndnd, s
 | 
						|
fndloop:    CPA     0, i
 | 
						|
            BREQ    notfnd
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            LDA     lstfndnd, sxf
 | 
						|
            CPA     lstfndel, s
 | 
						|
            BREQ    found
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lstfndnd, sxf
 | 
						|
            STA     lstfndnd, s
 | 
						|
            BR      fndloop
 | 
						|
notfnd:     LDA     0, i
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
found:      LDA     1, i
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
; Pointer to the list
 | 
						|
lstfndlp:   .EQUATE 0
 | 
						|
; Element to search
 | 
						|
lstfndel:   .EQUATE 2
 | 
						|
; Current node
 | 
						|
lstfndnd:   .EQUATE 4
 | 
						|
 | 
						|
; Pushes a new element at the end of the list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;   - A: Element to push
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: 0 if all went well, an error code otherwise
 | 
						|
lstpsh:     SUBSP   8, i
 | 
						|
            STX     lpshlp, s
 | 
						|
            STA     lpshel, s
 | 
						|
            CALL    newnode
 | 
						|
            STX     lpshnd, s
 | 
						|
            LDX     lpshlp, s
 | 
						|
            CALL    listlen
 | 
						|
            CPA     0, i
 | 
						|
            BREQ    lpshshft
 | 
						|
            SUBA    1, i
 | 
						|
            LDX     lpshlp, s
 | 
						|
            CALL    nodeat
 | 
						|
            STX     lpshlnd, s
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lpshnd, s
 | 
						|
            STA     lpshlnd, sxf
 | 
						|
            LDA     lpshel, s
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            STA     lpshnd, sxf
 | 
						|
            ADDSP   8, i
 | 
						|
            RET0
 | 
						|
lpshshft:   LDX     lpshlp, s
 | 
						|
            LDA     lpshel, s
 | 
						|
            CALL    lstunshf
 | 
						|
            ADDSP   8, i
 | 
						|
            RET0
 | 
						|
; Pointer to the list     
 | 
						|
lpshlp:     .EQUATE 0
 | 
						|
; Element to add to the list
 | 
						|
lpshel:     .EQUATE 2
 | 
						|
; Node to add to the list
 | 
						|
lpshnd:     .EQUATE 4
 | 
						|
; Node to append
 | 
						|
lpshlnd:    .EQUATE 6
 | 
						|
 | 
						|
; Pops the last element of a list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: Element removed from the list
 | 
						|
lstpop:     SUBSP   6, i
 | 
						|
            STX     lpoplp, s
 | 
						|
            CALL    listlen
 | 
						|
            CPA     0, i
 | 
						|
            BRNE    poperrem
 | 
						|
            CPA     1, i
 | 
						|
            BREQ    popshft
 | 
						|
            SUBA    2, i
 | 
						|
            LDX     lpoplp, s
 | 
						|
            CALL    nodeat
 | 
						|
            STX     lpopndpr, s
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lpopndpr, sxf
 | 
						|
            LDA     0, i
 | 
						|
            LDX     nodenxt, i
 | 
						|
            STA     lpopndpr, sxf
 | 
						|
            STA     lpoplnd, s
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            LDA     lpoplnd, s
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
poperrem:   STRO    poperrsm, d
 | 
						|
            STOP
 | 
						|
popshft:    LDX     lpoplp, s
 | 
						|
            CALL    lstshft
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
; Pointer to the list
 | 
						|
lpoplp:     .EQUATE 0
 | 
						|
; Node to remove
 | 
						|
lpoplnd:    .EQUATE 2
 | 
						|
;New last node
 | 
						|
lpopndpr:   .EQUATE 4
 | 
						|
; Message to print when popping an empty list
 | 
						|
poperrsm:    .ASCII "Error: cannot pop an empty list.\n\x00"
 | 
						|
 | 
						|
; Inserts an element in a list at a given position
 | 
						|
;
 | 
						|
; REQUIRES: Non-empty list
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - SP + 2: Pointer to the list
 | 
						|
;   - SP + 4: Index to insert at
 | 
						|
;   - SP + 6: Element to add
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: Error code: 0 if all went well, -1 if index < 0, -2 if index > list.length
 | 
						|
lstinsat:   SUBSP   6, i
 | 
						|
            LDA     lstinsid, s
 | 
						|
            CPA     0, i
 | 
						|
            BRLT    lstinslz
 | 
						|
            BREQ    lstinush
 | 
						|
            LDX     lstinslp, s
 | 
						|
            CALL    listlen
 | 
						|
            CPA     lstinsel, s
 | 
						|
            BRLT    lstinsgl
 | 
						|
            BREQ    lstinpsh
 | 
						|
            LDX     lstinslp, s
 | 
						|
            LDA     lstinsel, s
 | 
						|
            SUBA    1, i
 | 
						|
            CALL    nodeat
 | 
						|
            STX     lstinsnd, s
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lstinsnd, sxf
 | 
						|
            STA     lstinscx, s
 | 
						|
            CALL    newnode
 | 
						|
            STX     lstinscn, s
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            LDA     lstinsel, s
 | 
						|
            STA     lstinscn, sxf
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lstinscx, s
 | 
						|
            STA     lstinscn, sxf
 | 
						|
            LDA     lstinscn, s
 | 
						|
            LDX     nodenxt, i
 | 
						|
            STA     lstinsnd, sxf
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
lstinush:   LDX     lstinslp, s
 | 
						|
            LDA     lstinsel, s
 | 
						|
            CALL    lstunshf
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
lstinpsh:   LDX     lstinslp, s
 | 
						|
            LDA     lstinsel, s
 | 
						|
            CALL    lstpsh
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
; Insert with index < 0
 | 
						|
lstinslz:   LDA     -1, i
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
; Insert with index > list.length
 | 
						|
lstinsgl:   LDA     -2, i
 | 
						|
            ADDSP   6, i
 | 
						|
            RET0
 | 
						|
; List pointer
 | 
						|
lstinslp:   .EQUATE 8
 | 
						|
; Index of the newly created node
 | 
						|
lstinsid:   .EQUATE 10
 | 
						|
; Element to add
 | 
						|
lstinsel:   .EQUATE 12
 | 
						|
; Node to change the pointer to the next
 | 
						|
lstinsnd:   .EQUATE 0
 | 
						|
; Node to insert
 | 
						|
lstinscn:   .EQUATE 2
 | 
						|
; Pointer to the node after the created one (might be null)
 | 
						|
lstinscx:   .EQUATE 4
 | 
						|
 | 
						|
; Removes a node at a given index in a list,
 | 
						|
; returns the element previously contained
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - X: Pointer to the list
 | 
						|
;   - A: Index of the element
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - A: Element removed
 | 
						|
;
 | 
						|
; Error:
 | 
						|
;   In case of error, the program aborts with an error message
 | 
						|
lstremat:   SUBSP   8, i
 | 
						|
            STX     lremlp, s
 | 
						|
            STA     lremid, s
 | 
						|
            CPA     0, i
 | 
						|
            BRLT    lstremob
 | 
						|
            BREQ    lstremz
 | 
						|
            CALL    listlen
 | 
						|
            CPA     lremid, s
 | 
						|
            BRGE    lstremob
 | 
						|
            SUBA    1, i
 | 
						|
            CPA     lremid, s
 | 
						|
            BREQ    lrempop
 | 
						|
            LDA     lremid, s
 | 
						|
            LDX     lremlp, s
 | 
						|
            CALL    nodeat
 | 
						|
            STX     lremnd, s
 | 
						|
            LDA     lremid, s
 | 
						|
            SUBA    1, i
 | 
						|
            LDX     lremlp, s
 | 
						|
            CALL    nodeat
 | 
						|
            STX     lrempnd, s
 | 
						|
            LDX     nodenxt, i
 | 
						|
            LDA     lremnd, sxf
 | 
						|
            STA     lrempnd, sxf
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            LDA     lremnd, sxf
 | 
						|
            ADDSP   8, i
 | 
						|
            RET0
 | 
						|
lstremz:    LDX     lremlp, s
 | 
						|
            CALL    lstshft
 | 
						|
            ADDSP   8, i
 | 
						|
            RET0
 | 
						|
lrempop:    LDX     lremlp, s
 | 
						|
            CALL    lstpop
 | 
						|
            ADDSP   8, i
 | 
						|
            RET0
 | 
						|
lstremob:   STRO    lremobst, d
 | 
						|
            DECO    lremid, s
 | 
						|
            CHARO   '\n', i
 | 
						|
            STOP
 | 
						|
; Pointer to the list
 | 
						|
lremlp:     .EQUATE 0
 | 
						|
; Index to remove an element at
 | 
						|
lremid:     .EQUATE 2
 | 
						|
; Pointer to the node before the removed element
 | 
						|
lrempnd:    .EQUATE 4
 | 
						|
; Pointer to the node to remove
 | 
						|
lremnd:     .EQUATE 6
 | 
						|
; Error out of bounds string for remove_at
 | 
						|
lremobst:   .ASCII "Error: Out of bounds in remove_at, index = \x00"
 | 
						|
 | 
						|
; Creates a new node from scratch
 | 
						|
; Sets its content to 0/NULL
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   void
 | 
						|
;
 | 
						|
; Return:
 | 
						|
;   - X: Address of the node
 | 
						|
newnode:    LDA     nodeln, i
 | 
						|
            SUBSP   2, i
 | 
						|
            CALL    new
 | 
						|
            STX     0, s
 | 
						|
            LDA     0, i
 | 
						|
            LDX     nodenxt, i
 | 
						|
            STA     0, sxf
 | 
						|
            LDX     nodeelmt, i
 | 
						|
            STA     0, sxf
 | 
						|
            LDX     0, s
 | 
						|
            ADDSP   2, i
 | 
						|
            RET0
 | 
						|
 | 
						|
; Allocates a new structure in the heap
 | 
						|
;
 | 
						|
; Parameters:
 | 
						|
;   - A: Length of the structure to allocate (bytes)
 | 
						|
;
 | 
						|
; Returns:
 | 
						|
;   - X: Address of the allocated structure
 | 
						|
new:        ADDA    hpptr, d
 | 
						|
            LDX     hpptr, d
 | 
						|
            STA     hpptr, d
 | 
						|
            RET0
 | 
						|
 | 
						|
; Node in a linked list
 | 
						|
;
 | 
						|
; Contains two fields:
 | 
						|
;   - Element: Offset 0
 | 
						|
;   - Next: Offset 2
 | 
						|
;
 | 
						|
nodeln:     .EQUATE 4
 | 
						|
nodeelmt:   .EQUATE 0
 | 
						|
nodenxt:    .EQUATE 2
 | 
						|
 | 
						|
; Linked list capsule
 | 
						|
;
 | 
						|
; Contains one field:
 | 
						|
;   - Head: Offset 0
 | 
						|
;
 | 
						|
lstlen:     .EQUATE 2
 | 
						|
lsthead:    .EQUATE 0
 | 
						|
 | 
						|
; Pointer to the next available byte on the heap
 | 
						|
hpptr:      .ADDRSS heap
 | 
						|
; Start of the heap
 | 
						|
heap:       .BLOCK 1
 | 
						|
    .END
 |