zdebel gist felülvizsgálása 10 months ago. Revízióhoz ugrás
1 file changed, 227 insertions
gistfile1.txt(fájl létrehozva)
| @@ -0,0 +1,227 @@ | |||
| 1 | + | Adding Logo command parsing from a buffer in 6502 assembly requires handling string manipulation and tokenization. Below is an extended version of the previous code that includes a simple parser to read commands from a buffer and execute them. | |
| 2 | + | ||
| 3 | + | ### Assumptions | |
| 4 | + | 1. The input buffer contains a sequence of Logo commands separated by spaces or newlines. | |
| 5 | + | 2. Commands are in uppercase (e.g., `FORWARD 10`, `RIGHT 90`, `PENUP`). | |
| 6 | + | 3. The buffer is null-terminated. | |
| 7 | + | ||
| 8 | + | ### Updated 6502 Assembly Code | |
| 9 | + | ||
| 10 | + | ```assembly | |
| 11 | + | ; Constants | |
| 12 | + | TURTLE_X = $0200 ; Turtle X position | |
| 13 | + | TURTLE_Y = $0201 ; Turtle Y position | |
| 14 | + | TURTLE_DIR = $0202 ; Turtle direction (0=right, 1=down, 2=left, 3=up) | |
| 15 | + | PEN_STATE = $0203 ; Pen state (0=up, 1=down) | |
| 16 | + | INPUT_BUFFER = $0300 ; Input buffer for commands | |
| 17 | + | BUFFER_PTR = $0204 ; Pointer to current position in input buffer | |
| 18 | + | ||
| 19 | + | ; Initialize turtle and buffer pointer | |
| 20 | + | LDA #$00 | |
| 21 | + | STA TURTLE_X ; Start at X=0 | |
| 22 | + | STA TURTLE_Y ; Start at Y=0 | |
| 23 | + | STA TURTLE_DIR ; Start facing right | |
| 24 | + | STA PEN_STATE ; Start with pen down | |
| 25 | + | LDA #<INPUT_BUFFER | |
| 26 | + | STA BUFFER_PTR ; Initialize buffer pointer to start of input buffer | |
| 27 | + | LDA #>INPUT_BUFFER | |
| 28 | + | STA BUFFER_PTR+1 | |
| 29 | + | ||
| 30 | + | ; Main loop | |
| 31 | + | MainLoop: | |
| 32 | + | JSR ReadCommand ; Read a command | |
| 33 | + | JSR ExecuteCommand ; Execute the command | |
| 34 | + | JMP MainLoop ; Repeat | |
| 35 | + | ||
| 36 | + | ; ReadCommand: Read a command from the input buffer | |
| 37 | + | ReadCommand: | |
| 38 | + | LDY #$00 ; Reset Y for buffer indexing | |
| 39 | + | JSR SkipWhitespace ; Skip leading whitespace | |
| 40 | + | JSR ReadToken ; Read the command token | |
| 41 | + | RTS | |
| 42 | + | ||
| 43 | + | ; SkipWhitespace: Skip spaces and newlines in the buffer | |
| 44 | + | SkipWhitespace: | |
| 45 | + | LDA (BUFFER_PTR), Y | |
| 46 | + | CMP #' ' ; Space | |
| 47 | + | BEQ .NextChar | |
| 48 | + | CMP #$0A ; Newline | |
| 49 | + | BEQ .NextChar | |
| 50 | + | RTS | |
| 51 | + | .NextChar: | |
| 52 | + | INY | |
| 53 | + | JMP SkipWhitespace | |
| 54 | + | ||
| 55 | + | ; ReadToken: Read a token from the buffer | |
| 56 | + | ReadToken: | |
| 57 | + | LDX #$00 ; X will index into the token buffer | |
| 58 | + | .ReadChar: | |
| 59 | + | LDA (BUFFER_PTR), Y | |
| 60 | + | BEQ .EndOfBuffer ; End of buffer | |
| 61 | + | CMP #' ' ; Space | |
| 62 | + | BEQ .EndOfToken | |
| 63 | + | CMP #$0A ; Newline | |
| 64 | + | BEQ .EndOfToken | |
| 65 | + | STA TOKEN_BUFFER, X | |
| 66 | + | INX | |
| 67 | + | INY | |
| 68 | + | JMP .ReadChar | |
| 69 | + | .EndOfToken: | |
| 70 | + | LDA #$00 ; Null-terminate the token | |
| 71 | + | STA TOKEN_BUFFER, X | |
| 72 | + | INY ; Move past the space/newline | |
| 73 | + | RTS | |
| 74 | + | .EndOfBuffer: | |
| 75 | + | LDA #$00 ; Null-terminate the token | |
| 76 | + | STA TOKEN_BUFFER, X | |
| 77 | + | RTS | |
| 78 | + | ||
| 79 | + | ; ExecuteCommand: Execute the command in TOKEN_BUFFER | |
| 80 | + | ExecuteCommand: | |
| 81 | + | LDX #$00 | |
| 82 | + | .CompareCommand: | |
| 83 | + | LDA TOKEN_BUFFER, X | |
| 84 | + | CMP COMMAND_FORWARD, X | |
| 85 | + | BNE .NotForward | |
| 86 | + | INX | |
| 87 | + | CPX #7 ; Length of "FORWARD" | |
| 88 | + | BNE .CompareCommand | |
| 89 | + | JSR ParseNumber ; Parse the number argument | |
| 90 | + | JSR MoveForward ; Execute FORWARD command | |
| 91 | + | RTS | |
| 92 | + | .NotForward: | |
| 93 | + | ; Repeat for other commands (RIGHT, LEFT, PENUP, PENDOWN) | |
| 94 | + | ; Example for RIGHT: | |
| 95 | + | LDX #$00 | |
| 96 | + | .CompareRight: | |
| 97 | + | LDA TOKEN_BUFFER, X | |
| 98 | + | CMP COMMAND_RIGHT, X | |
| 99 | + | BNE .NotRight | |
| 100 | + | INX | |
| 101 | + | CPX #5 ; Length of "RIGHT" | |
| 102 | + | BNE .CompareRight | |
| 103 | + | JSR ParseNumber ; Parse the number argument | |
| 104 | + | JSR TurnRight ; Execute RIGHT command | |
| 105 | + | RTS | |
| 106 | + | .NotRight: | |
| 107 | + | ; Add similar blocks for LEFT, PENUP, PENDOWN | |
| 108 | + | RTS | |
| 109 | + | ||
| 110 | + | ; ParseNumber: Parse a number from the buffer | |
| 111 | + | ParseNumber: | |
| 112 | + | LDY #$00 | |
| 113 | + | LDA #$00 | |
| 114 | + | STA NUMBER ; Reset number | |
| 115 | + | .ParseDigit: | |
| 116 | + | LDA (BUFFER_PTR), Y | |
| 117 | + | CMP #'0' | |
| 118 | + | BCC .EndParse ; Not a digit | |
| 119 | + | CMP #'9'+1 | |
| 120 | + | BCS .EndParse ; Not a digit | |
| 121 | + | SEC | |
| 122 | + | SBC #'0' ; Convert ASCII to number | |
| 123 | + | PHA ; Save digit | |
| 124 | + | LDA NUMBER | |
| 125 | + | ASL A ; Multiply by 10 | |
| 126 | + | STA TEMP | |
| 127 | + | ASL A | |
| 128 | + | ASL A | |
| 129 | + | CLC | |
| 130 | + | ADC TEMP | |
| 131 | + | ADC #$00 ; Add new digit | |
| 132 | + | STA NUMBER | |
| 133 | + | PLA ; Restore digit | |
| 134 | + | INY | |
| 135 | + | JMP .ParseDigit | |
| 136 | + | .EndParse: | |
| 137 | + | RTS | |
| 138 | + | ||
| 139 | + | ; MoveForward: Move the turtle forward by n steps | |
| 140 | + | MoveForward: | |
| 141 | + | LDX TURTLE_DIR | |
| 142 | + | LDA TURTLE_X | |
| 143 | + | CLC | |
| 144 | + | ADC ForwardDeltaX, X | |
| 145 | + | STA TURTLE_X | |
| 146 | + | LDA TURTLE_Y | |
| 147 | + | CLC | |
| 148 | + | ADC ForwardDeltaY, X | |
| 149 | + | STA TURTLE_Y | |
| 150 | + | RTS | |
| 151 | + | ||
| 152 | + | ForwardDeltaX: | |
| 153 | + | .byte 1, 0, -1, 0 ; Delta X for each direction | |
| 154 | + | ForwardDeltaY: | |
| 155 | + | .byte 0, 1, 0, -1 ; Delta Y for each direction | |
| 156 | + | ||
| 157 | + | ; TurnRight: Turn the turtle right by d degrees | |
| 158 | + | TurnRight: | |
| 159 | + | LDA TURTLE_DIR | |
| 160 | + | CLC | |
| 161 | + | ADC #1 | |
| 162 | + | AND #$03 ; Wrap around after 3 | |
| 163 | + | STA TURTLE_DIR | |
| 164 | + | RTS | |
| 165 | + | ||
| 166 | + | ; TurnLeft: Turn the turtle left by d degrees | |
| 167 | + | TurnLeft: | |
| 168 | + | LDA TURTLE_DIR | |
| 169 | + | SEC | |
| 170 | + | SBC #1 | |
| 171 | + | AND #$03 ; Wrap around after 3 | |
| 172 | + | STA TURTLE_DIR | |
| 173 | + | RTS | |
| 174 | + | ||
| 175 | + | ; PenUp: Lift the pen | |
| 176 | + | PenUp: | |
| 177 | + | LDA #$00 | |
| 178 | + | STA PEN_STATE | |
| 179 | + | RTS | |
| 180 | + | ||
| 181 | + | ; PenDown: Lower the pen | |
| 182 | + | PenDown: | |
| 183 | + | LDA #$01 | |
| 184 | + | STA PEN_STATE | |
| 185 | + | RTS | |
| 186 | + | ||
| 187 | + | ; Data | |
| 188 | + | COMMAND_FORWARD: | |
| 189 | + | .byte "FORWARD", 0 | |
| 190 | + | COMMAND_RIGHT: | |
| 191 | + | .byte "RIGHT", 0 | |
| 192 | + | COMMAND_LEFT: | |
| 193 | + | .byte "LEFT", 0 | |
| 194 | + | COMMAND_PENUP: | |
| 195 | + | .byte "PENUP", 0 | |
| 196 | + | COMMAND_PENDOWN: | |
| 197 | + | .byte "PENDOWN", 0 | |
| 198 | + | ||
| 199 | + | TOKEN_BUFFER: | |
| 200 | + | .res 16 ; Reserve 16 bytes for token buffer | |
| 201 | + | NUMBER: | |
| 202 | + | .byte 0 ; Storage for parsed number | |
| 203 | + | TEMP: | |
| 204 | + | .byte 0 ; Temporary storage | |
| 205 | + | ``` | |
| 206 | + | ||
| 207 | + | ### Explanation of Changes | |
| 208 | + | ||
| 209 | + | 1. **Input Buffer**: The `INPUT_BUFFER` holds the Logo commands. The `BUFFER_PTR` keeps track of the current position in the buffer. | |
| 210 | + | 2. **Tokenization**: The `ReadToken` routine reads a command or argument from the buffer into `TOKEN_BUFFER`. | |
| 211 | + | 3. **Command Parsing**: The `ExecuteCommand` routine compares the token with known commands (`FORWARD`, `RIGHT`, etc.) and calls the appropriate subroutine. | |
| 212 | + | 4. **Number Parsing**: The `ParseNumber` routine converts ASCII digits in the buffer to a binary number. | |
| 213 | + | 5. **Command Execution**: The `MoveForward`, `TurnRight`, `TurnLeft`, `PenUp`, and `PenDown` routines implement the Logo commands. | |
| 214 | + | ||
| 215 | + | ### Example Input Buffer | |
| 216 | + | If the input buffer contains: | |
| 217 | + | ``` | |
| 218 | + | FORWARD 10 RIGHT 90 FORWARD 20 PENUP | |
| 219 | + | ``` | |
| 220 | + | The program will parse and execute these commands sequentially. | |
| 221 | + | ||
| 222 | + | ### Limitations | |
| 223 | + | - This implementation assumes fixed-format input (e.g., no lowercase commands). | |
| 224 | + | - Error handling is minimal; invalid commands or numbers will cause undefined behavior. | |
| 225 | + | - The buffer size and token buffer size are fixed and may need adjustment for larger inputs. | |
| 226 | + | ||
| 227 | + | This code provides a basic framework for parsing and executing Logo commands in 6502 assembly. You can expand it further to handle more commands, error checking, and graphics output. | |
Újabb
Régebbi