0001 0000 ;ROM system monitor 0002 0000 ;Macro definitions for three levels of nested call and ret 0003 0000 #define call0(address) \return: .set $+15\ ldm return\ stm return_jump0+1\ ldm return+1\ stm return_jump0+2 0004 0000 #defcont \ jmp address\ .dw $+2 0005 0000 #define ret0 \ jmp return_jump0 0006 0000 #define call1(address) \return: .set $+15\ ldm return\ stm return_jump1+1\ ldm return+1\ stm return_jump1+2 0007 0000 #defcont \ jmp address\ .dw $+2 0008 0000 #define ret1 \ jmp return_jump1 0009 0000 #define call2(address) \return: .set $+15\ ldm return\ stm return_jump2+1\ ldm return+1\ stm return_jump2+2 0010 0000 #defcont \ jmp address\ .dw $+2 0011 0000 #define ret2 \ jmp return_jump2 0012 0000 0013 0000 ;Buffer location defined by these constant values 0014 0000 ;Needs to be in RAM above variables and variable instructions 0015 0000 buff_low: .equ 80h ;low byte of buffer address 0016 0000 buff_high: .equ 08h ;high byte of buffer address 0017 0000 buffer: .equ 0880h ;two-byte address constant 0018 0000 .org 0000h 0019 0000 0020 0000 1F return: .db 1fh ;placeholder for first definition of variable label -- NOP 0021 0001 0022 0001 ;Initialize port 0023 0001 10 4E LDI 4EH ;1 stop bit, no parity, 8-bit char, 16x baud 0024 0003 18 03 OUT 03H ;write to UART control port 0025 0005 10 37 LDI 37H ;enable receive and transmit 0026 0007 18 03 OUT 03H ;write to control port 0027 0009 0028 0009 ;Opcode initialization for RAM instructions 0029 0009 10 13 ldi 13h ;jmp opcode 0030 000B 12 1E 08 stm ld_indexed_stm+3 ;return jumps for indexed instructions 0031 000E 12 24 08 stm d_indexed_ldm+3 0032 0011 12 2A 08 stm d_indexed_stm+3 0033 0014 12 30 08 stm bl_indexed_stm+3 0034 0017 12 36 08 stm ws_inst+3 0035 001A 12 3C 08 stm gl_indexed_stm+3 0036 001D 12 3F 08 stm return_jump0 ;other variable jumps 0037 0020 12 42 08 stm return_jump1 0038 0023 12 45 08 stm return_jump2 0039 0026 12 18 08 stm run_jump 0040 0029 10 12 ldi 12h ;stm opcode 0041 002B 12 1B 08 stm ld_indexed_stm ;indexed store instructions 0042 002E 12 27 08 stm d_indexed_stm 0043 0031 12 2D 08 stm bl_indexed_stm 0044 0034 12 39 08 stm gl_indexed_stm 0045 0037 10 11 ldi 11h ;ldm opcode 0046 0039 12 21 08 stm d_indexed_ldm 0047 003C 12 33 08 stm ws_inst 0048 003F 10 00 ldi 00h ;address of ld_stm_back 0049 0041 12 1F 08 stm ld_indexed_stm+4 0050 0044 10 03 ldi 03h 0051 0046 12 20 08 stm ld_indexed_stm+5 0052 0049 10 59 ldi 59h ;address of d_ldm_back 0053 004B 12 25 08 stm d_indexed_ldm+4 0054 004E 10 01 ldi 01h 0055 0050 12 26 08 stm d_indexed_ldm+5 0056 0053 10 78 ldi 78h ;address of d_stm_back 0057 0055 12 2B 08 stm d_indexed_stm+4 0058 0058 10 01 ldi 01h 0059 005A 12 2C 08 stm d_indexed_stm+5 0060 005D 10 B2 ldi 0b2h ;address of bl_back 0061 005F 12 31 08 stm bl_indexed_stm+4 0062 0062 10 04 ldi 04h 0063 0064 12 32 08 stm bl_indexed_stm+5 0064 0067 10 F1 ldi 0f1h ;address of ws_back 0065 0069 12 37 08 stm ws_inst+4 0066 006C 10 05 ldi 05h 0067 006E 12 38 08 stm ws_inst+5 0068 0071 10 C0 ldi 0C0h ;address of gl_back 0069 0073 12 3D 08 stm gl_indexed_stm+4 0070 0076 10 05 ldi 05h 0071 0078 12 3E 08 stm gl_indexed_stm+5 0072 007B 0073 007B ;Print greeting 0074 007B 11 36 07 sm_lukewarm ldm sm_greeting 0075 007E 12 34 08 stm ws_inst+1 0076 0081 11 37 07 ldm sm_greeting+1 0077 0084 12 35 08 stm ws_inst+2 0078 0087 call0(write_string) 0078 0087 0078 0087 11 96 00 0078 008A 12 40 08 0078 008D 11 97 00 0078 0090 12 41 08 0078 0093 13 E7 05 0078 0096 98 00 0079 0098 0080 0098 ;Warm start for system monitor, re-entry point after commands have finished 0081 0098 ;Prompt for routine number input 0082 0098 11 68 07 sm_warm ldm sm_prompt 0083 009B 12 34 08 stm ws_inst+1 0084 009E 11 69 07 ldm sm_prompt+1 0085 00A1 12 35 08 stm ws_inst+2 0086 00A4 call0(write_string) 0086 00A4 0086 00A4 11 B3 00 0086 00A7 12 40 08 0086 00AA 11 B4 00 0086 00AD 12 41 08 0086 00B0 13 E7 05 0086 00B3 B5 00 0087 00B5 0088 00B5 ;Get character and jump to monitor routine 0089 00B5 17 03 sm_chk_loop: in 03h ;get status 0090 00B7 0C 02 andim 02h ;check RxRDY 0091 00B9 14 B5 00 jpz sm_chk_loop 0092 00BC 17 02 in 02h ;get char from port and echo 0093 00BE 12 11 08 stm choice 0094 00C1 17 03 sm_echo_loop in 03h 0095 00C3 0C 01 andim 01h ;check TxRDY 0096 00C5 14 C1 00 jpz sm_echo_loop 0097 00C8 11 11 08 ldm choice 0098 00CB 18 02 out 02h 0099 00CD 0F 35 cmp '5' 0100 00CF 16 15 03 jpc sm_bload 0101 00D2 0F 34 cmp '4' 0102 00D4 16 09 02 jpc sm_load 0103 00D7 0F 33 cmp '3' 0104 00D9 16 F7 01 jpc sm_run 0105 00DC 0F 32 cmp '2' 0106 00DE 16 E4 00 jpc sm_dump 0107 00E1 13 98 00 jmp sm_warm ;any number other than 2 to 5 results in warm restart 0108 00E4 0109 00E4 ;Memory dump routine 0110 00E4 ;Get address from input string 0111 00E4 13 E2 04 sm_dump jmp get_address 0112 00E7 11 0E 08 d_addr_back ldm address 0113 00EA 12 22 08 stm d_indexed_ldm+1 0114 00ED 11 0F 08 ldm address+1 0115 00F0 12 23 08 stm d_indexed_ldm+2 0116 00F3 0117 00F3 ;Dump 16 lines of 16 characters each 0118 00F3 ;Set up line counter 0119 00F3 10 10 ldi 16 0120 00F5 12 14 08 stm line_counter 0121 00F8 ;Loop for putting a memory dump line in the buffer 0122 00F8 ;Start with 4 characters of the starting address of the line, followed by space 0123 00F8 11 23 08 d_line_loop ldm d_indexed_ldm+2 ;high byte of memory address 0124 00FB 12 12 08 stm byte 0125 00FE call0(byte_to_hex_pair) 0125 00FE 0125 00FE 11 0D 01 0125 0101 12 40 08 0125 0104 11 0E 01 0125 0107 12 41 08 0125 010A 13 B4 06 0125 010D 0F 01 0126 010F 11 0A 08 ldm char_pair 0127 0112 12 80 08 stm buffer ;start of line 0128 0115 11 0B 08 ldm char_pair+1 0129 0118 12 81 08 stm buffer+1 0130 011B 11 22 08 ldm d_indexed_ldm+1 ;low byte of memory address 0131 011E 12 12 08 stm byte 0132 0121 call0(byte_to_hex_pair) 0132 0121 0132 0121 11 30 01 0132 0124 12 40 08 0132 0127 11 31 01 0132 012A 12 41 08 0132 012D 13 B4 06 0132 0130 32 01 0133 0132 11 0A 08 ldm char_pair 0134 0135 12 82 08 stm buffer+2 0135 0138 11 0B 08 ldm char_pair+1 0136 013B 12 83 08 stm buffer+3 0137 013E 10 20 ldi 20h ;space character 0138 0140 12 84 08 stm buffer+4 0139 0143 ;Set up for getting 16 memory bytes, converting to characters, and putting in string buffer 0140 0143 10 80 ldi buff_low 0141 0145 08 05 addim 5 0142 0147 12 28 08 stm d_indexed_stm+1 ;low byte of location of first character in output string 0143 014A 10 08 ldi buff_high 0144 014C 09 00 adcim 0 ;16-bit addition 0145 014E 12 29 08 stm d_indexed_stm+2 ;high byte of location of first character in output string 0146 0151 10 10 ldi 16 0147 0153 12 16 08 stm byte_counter ;number of bytes to get, convert, and display in one line 0148 0156 13 21 08 d_byte_loop: jmp d_indexed_ldm ;get byte from memory 0149 0159 12 12 08 d_ldm_back: stm byte 0150 015C call0(byte_to_hex_pair) ;convert to hex pair 0150 015C 0150 015C 11 6B 01 0150 015F 12 40 08 0150 0162 11 6C 01 0150 0165 12 41 08 0150 0168 13 B4 06 0150 016B 6D 01 0151 016D 10 03 ldi 3 0152 016F 12 17 08 stm nybble_counter 0153 0172 11 0A 08 ldm char_pair 0154 0175 13 27 08 d_nybble_loop: jmp d_indexed_stm ;store char of byte in string buffer 0155 0178 11 28 08 d_stm_back: ldm d_indexed_stm+1 ;increment pointer by 16-bit incrementation 0156 017B 19 inc 0157 017C 12 28 08 stm d_indexed_stm+1 0158 017F 11 29 08 ldm d_indexed_stm+2 0159 0182 09 00 adcim 0 0160 0184 12 29 08 stm d_indexed_stm+2 ;pointing to next spot in buffer 0161 0187 11 17 08 ldm nybble_counter 0162 018A 1A dec ;all three characters stored (hex chars plus space)? 0163 018B 14 A1 01 jpz d_nybble_done ;yes, next byte 0164 018E 12 17 08 stm nybble_counter ;no, place next character or space 0165 0191 0A 01 subim 1 ;if nybble count = 1, put a space next 0166 0193 14 9C 01 jpz d_put_space 0167 0196 11 0B 08 ldm char_pair+1 ;otherwise, get next char and store 0168 0199 13 75 01 jmp d_nybble_loop 0169 019C 10 20 d_put_space: ldi 20h ;space character 0170 019E 13 75 01 jmp d_nybble_loop 0171 01A1 11 22 08 d_nybble_done: ldm d_indexed_ldm+1 ;increment memory pointer 0172 01A4 19 inc 0173 01A5 12 22 08 stm d_indexed_ldm+1 0174 01A8 11 23 08 ldm d_indexed_ldm+2 0175 01AB 09 00 adcim 0 0176 01AD 12 23 08 stm d_indexed_ldm+2 0177 01B0 11 16 08 ldm byte_counter 0178 01B3 1A dec 0179 01B4 14 BD 01 jpz d_line_done 0180 01B7 12 16 08 stm byte_counter 0181 01BA 13 56 01 jmp d_byte_loop 0182 01BD 10 0D d_line_done: ldi 0dh ;newline characters 0183 01BF 12 B4 08 stm buffer+52 0184 01C2 10 0A ldi 0ah 0185 01C4 12 B5 08 stm buffer+53 0186 01C7 10 00 ldi 0 0187 01C9 12 B6 08 stm buffer+54 ;where the end of the line will be 0188 01CC ;Write string to screen 0189 01CC 10 80 ldi buff_low 0190 01CE 12 34 08 stm ws_inst+1 0191 01D1 10 08 ldi buff_high 0192 01D3 12 35 08 stm ws_inst+2 0193 01D6 call0(write_string) 0193 01D6 0193 01D6 11 E5 01 0193 01D9 12 40 08 0193 01DC 11 E6 01 0193 01DF 12 41 08 0193 01E2 13 E7 05 0193 01E5 E7 01 0194 01E7 0195 01E7 ;Check if 16 lines done 0196 01E7 11 14 08 ldm line_counter 0197 01EA 1A dec 0198 01EB 14 F4 01 jpz d_done 0199 01EE 12 14 08 stm line_counter 0200 01F1 13 F8 00 jmp d_line_loop 0201 01F4 d_done: 0202 01F4 13 98 00 error: jmp sm_warm 0203 01F7 0204 01F7 ;Monitor routine to jump and execute code 0205 01F7 ;Gets target address from terminal 0206 01F7 0207 01F7 13 E2 04 sm_run jmp get_address 0208 01FA 11 0E 08 run_addr_back ldm address 0209 01FD 12 19 08 stm run_jump+1 0210 0200 11 0F 08 ldm address+1 0211 0203 12 1A 08 stm run_jump+2 0212 0206 13 18 08 jmp run_jump 0213 0209 0214 0209 ;Routine to get hex char pairs from input and load bytes in RAM 0215 0209 ;Get address first 0216 0209 13 E2 04 sm_load jmp get_address 0217 020C 11 0E 08 ld_addr_back ldm address 0218 020F 12 1C 08 stm ld_indexed_stm+1 0219 0212 11 0F 08 ldm address+1 0220 0215 12 1D 08 stm ld_indexed_stm+2 0221 0218 ;Initialize display bytes counter 0222 0218 10 10 ldi 10h ;16 bytes per line 0223 021A 12 16 08 stm byte_counter 0224 021D ;Get characters 0225 021D ;First character of pair 0226 021D 17 03 ld_get_hi: IN 03H ;Get hi-order nybble of pair 0227 021F 0C 02 ANDIM 02H ;check RxRDY bit 0228 0221 14 1D 02 JPZ ld_get_hi ;not ready, loop 0229 0224 17 02 IN 02H ;get char from data port 0230 0226 12 10 08 STM temp ;Store character 0231 0229 0A 0D SUBIM 0DH ;Carriage return? 0232 022B 14 12 03 JPZ ld_done ;Yes, return to monitor 0233 022E 17 03 ld_loop_1: IN 03H ;No, output character and validate 0234 0230 0C 01 ANDIM 01H ;check TxRDY bit 0235 0232 14 2E 02 JPZ ld_loop_1 ;loop if not ready 0236 0235 11 10 08 LDM temp ;get char back 0237 0238 18 02 OUT 02H ;send to UART for output 0238 023A ;Code to validate hex character 0239 023A 0F 30 CMP 30H ;Lower limit of hex characters 0240 023C 16 42 02 JPC ld_next_1 ;Char >= 30H, possibly valid 0241 023F 13 60 02 JMP ld_invalid ;Char < 30H, invalid hex char 0242 0242 0F 47 ld_next_1: CMP 47H ;ASCII for "G" 0243 0244 16 60 02 JPC ld_invalid ;Char is G or greater, invalid 0244 0247 0F 41 CMP 41H ;ASCII for "A" 0245 0249 16 54 02 JPC ld_validAF_hi ;Char is valid A-F 0246 024C 0F 3A CMP 3AH ;ASCII for ":" 0247 024E 16 60 02 JPC ld_invalid ;Char is ":" or greater, but < "A", invalid 0248 0251 13 5B 02 JMP ld_valid09_hi ;Char is valid 0-9 0249 0254 0C 0F ld_validAF_hi: ANDIM 0FH ;Mask off high bits 0250 0256 08 09 ADDIM 9 ;Adjust ASCII to binary value 0251 0258 13 63 02 JMP ld_shift_hi 0252 025B 0C 0F ld_valid09_hi: ANDIM 0FH ;Mask off high bits 0253 025D 13 63 02 JMP ld_shift_hi 0254 0260 13 12 03 ld_invalid: JMP ld_error ;Invalid hex char, quit 0255 0263 12 12 08 ld_shift_hi: STM byte ;Will eventually contain the byte to load 0256 0266 12 10 08 STM temp ;Value to add 0257 0269 10 10 LDI 10H ;Multiply x 16 to shift into high-order nybble 0258 026B 12 13 08 STM counter 0259 026E 11 13 08 ld_multloop: LDM counter 0260 0271 1A DEC 0261 0272 14 84 02 JPZ ld_get_lo ;Have added 16 times, done 0262 0275 12 13 08 STM counter 0263 0278 11 10 08 LDM temp ;Original nybble 0264 027B 00 12 08 ADD byte ;Add to BYTE and store 0265 027E 12 12 08 STM byte 0266 0281 13 6E 02 JMP ld_multloop ;Keep adding 0267 0284 17 03 ld_get_lo: IN 03H ;Get lo-order nybble of pair 0268 0286 0C 02 ANDIM 02H ;check RxRDY bit 0269 0288 14 84 02 JPZ ld_get_lo ;not ready, loop 0270 028B 17 02 IN 02H ;get char from data port 0271 028D 12 10 08 STM temp ;Store character 0272 0290 17 03 ld_loop2: IN 03H ;Output character 0273 0292 0C 01 ANDIM 01H ;check TxRDY bit 0274 0294 14 90 02 JPZ ld_loop2 0275 0297 11 10 08 LDM temp ;When ready, retrieve character and output 0276 029A 18 02 OUT 02H 0277 029C 17 03 ld_loop3: IN 03H 0278 029E 0C 01 ANDIM 01H 0279 02A0 14 9C 02 JPZ ld_loop3 0280 02A3 10 20 LDI 20H ;Space character 0281 02A5 18 02 OUT 02H ;send to UART for output 0282 02A7 11 16 08 ldm byte_counter ;Check if 16 bytes have been displayed 0283 02AA 1A dec 0284 02AB 12 16 08 stm byte_counter 0285 02AE 14 B4 02 jpz ld_next4 ;Yes, reset counter and write newline 0286 02B1 13 CF 02 jmp ld_next5 ;No, keep going 0287 02B4 10 10 ld_next4: ldi 10h 0288 02B6 12 16 08 stm byte_counter 0289 02B9 ;Write newline 0290 02B9 17 03 ld_loop4: IN 03H 0291 02BB 0C 01 ANDIM 01H 0292 02BD 14 B9 02 JPZ ld_loop4 0293 02C0 10 0D LDI 0DH ;Return character 0294 02C2 18 02 OUT 02H ;send to UART for output 0295 02C4 17 03 ld_loop5: IN 03H 0296 02C6 0C 01 ANDIM 01H 0297 02C8 14 C4 02 JPZ ld_loop5 0298 02CB 10 0A LDI 0AH ;Linefeed character 0299 02CD 18 02 OUT 02H ;send to UART for output 0300 02CF ;Code to validate hex character 0301 02CF 11 10 08 ld_next5: LDM temp ;Retrieve character and validate 0302 02D2 0F 30 CMP 30H ;Lower limit of hex characters 0303 02D4 16 DA 02 JPC ld_next2 ;Char >= 30H, possibly valid 0304 02D7 13 60 02 JMP ld_invalid ;Char < 30H, invalid hex char 0305 02DA 0F 47 ld_next2: CMP 47H ;ASCII for "G" 0306 02DC 16 60 02 JPC ld_invalid ;Char is G or greater, invalid 0307 02DF 0F 41 CMP 41H ;ASCII for "A" 0308 02E1 16 EC 02 JPC ld_validAF_lo ;Char is valid A-F 0309 02E4 0F 3A CMP 3AH ;ASCII for ":" 0310 02E6 16 60 02 JPC ld_invalid ;Char is ":" or greater, but < "A", invalid 0311 02E9 13 F6 02 JMP ld_valid09_lo ;Char is valid 0-9 0312 02EC 0C 0F ld_validAF_lo: ANDIM 0FH ;Mask off high bits 0313 02EE 08 09 ADDIM 9 ;Now lo nybble correct 0314 02F0 00 12 08 ADD byte ;Combine with hi nybble stored in BYTE 0315 02F3 13 1B 08 JMP ld_indexed_stm ;Store the byte in RAM 0316 02F6 0C 0F ld_valid09_lo: ANDIM 0FH ;Mask off high bits 0317 02F8 00 12 08 ADD byte ;Now full byte assembled 0318 02FB 18 00 OUT 00H ;Display on LEDs 0319 02FD 13 1B 08 JMP ld_indexed_stm ;Store the byte in RAM 0320 0300 11 1C 08 ld_stm_back: LDM ld_indexed_stm+1 ;Increment byte pointer, lo byte first 0321 0303 19 INC 0322 0304 12 1C 08 STM ld_indexed_stm+1 0323 0307 11 1D 08 LDM ld_indexed_stm+2 ;Increment hi byte if a carry occurred when lo byte incremented 0324 030A 09 00 ADCIM 00H 0325 030C 12 1D 08 STM ld_indexed_stm+2 0326 030F 13 1D 02 JMP ld_get_hi 0327 0312 ld_done: 0328 0312 13 98 00 ld_error: JMP sm_warm ;Return to monitor 0329 0315 0330 0315 ;Monitor routine for binary load 0331 0315 ;Gets load target address and number of bytes from terminal 0332 0315 ;Loads bytes in RAM and returns to monitor 0333 0315 13 E2 04 sm_bload jmp get_address 0334 0318 11 0E 08 bl_addr_back ldm address 0335 031B 12 2E 08 stm bl_indexed_stm+1 0336 031E 11 0F 08 ldm address+1 0337 0321 12 2F 08 stm bl_indexed_stm+2 0338 0324 0339 0324 ;Gets number of bytes in decimal from input using get_line, called as level 0 subroutine 0340 0324 ;Write newline 0341 0324 11 B5 07 bl_get_bytes ldm bytes_str 0342 0327 12 34 08 stm ws_inst+1 0343 032A 11 B6 07 ldm bytes_str+1 0344 032D 12 35 08 stm ws_inst+2 0345 0330 call0(write_string) 0345 0330 0345 0330 11 3F 03 0345 0333 12 40 08 0345 0336 11 40 03 0345 0339 12 41 08 0345 033C 13 E7 05 0345 033F 41 03 0346 0341 0347 0341 ;Get input decimal number string 0348 0341 call0(get_line) 0348 0341 0348 0341 11 50 03 0348 0344 12 40 08 0348 0347 11 51 03 0348 034A 12 41 08 0348 034D 13 8D 05 0348 0350 52 03 0349 0352 0350 0352 ;Get word value from input string 0351 0352 ;No error checking for final value -- must be between 0 and 65535 (0000 and FFFF hex) 0352 0352 ;No error checking for numerals -- must be 0 to 9 0353 0352 0354 0352 10 00 ldi 0 ;starting value 0355 0354 12 00 08 stm dp_value ;zero final value variable 0356 0357 12 01 08 stm dp_value+1 0357 035A 11 07 08 dp_input ldm gl_str_len ;input string length from get_line 0358 035D 0F 05 cmp 5 0359 035F 16 79 03 jpc dp_setup_5 0360 0362 0F 04 cmp 4 0361 0364 16 9A 03 jpc dp_setup_4 0362 0367 0F 03 cmp 3 0363 0369 16 B5 03 jpc dp_setup_3 0364 036C 0F 02 cmp 2 0365 036E 16 CA 03 jpc dp_setup_2 0366 0371 0F 01 cmp 1 0367 0373 16 D9 03 jpc dp_setup_1 0368 0376 13 98 00 jmp sm_warm 0369 0379 0370 0379 11 84 08 dp_setup_5 ldm buffer+4 0371 037C 12 06 08 stm dp_1s 0372 037F 11 83 08 ldm buffer+3 0373 0382 12 05 08 stm dp_10s 0374 0385 11 82 08 ldm buffer+2 0375 0388 12 04 08 stm dp_100s 0376 038B 11 81 08 ldm buffer+1 0377 038E 12 03 08 stm dp_1000s 0378 0391 11 80 08 ldm buffer 0379 0394 12 02 08 stm dp_10000s 0380 0397 13 E2 03 jmp dp_10000_mult 0381 039A 11 83 08 dp_setup_4 ldm buffer+3 0382 039D 12 06 08 stm dp_1s 0383 03A0 11 82 08 ldm buffer+2 0384 03A3 12 05 08 stm dp_10s 0385 03A6 11 81 08 ldm buffer+1 0386 03A9 12 04 08 stm dp_100s 0387 03AC 11 80 08 ldm buffer 0388 03AF 12 03 08 stm dp_1000s 0389 03B2 13 04 04 jmp dp_1000_mult 0390 03B5 11 82 08 dp_setup_3 ldm buffer+2 0391 03B8 12 06 08 stm dp_1s 0392 03BB 11 81 08 ldm buffer+1 0393 03BE 12 05 08 stm dp_10s 0394 03C1 11 80 08 ldm buffer 0395 03C4 12 04 08 stm dp_100s 0396 03C7 13 26 04 jmp dp_100_mult 0397 03CA 11 81 08 dp_setup_2 ldm buffer+1 0398 03CD 12 06 08 stm dp_1s 0399 03D0 11 80 08 ldm buffer 0400 03D3 12 05 08 stm dp_10s 0401 03D6 13 48 04 jmp dp_10_mult 0402 03D9 11 80 08 dp_setup_1 ldm buffer 0403 03DC 12 06 08 stm dp_1s 0404 03DF 13 6A 04 jmp dp_1_mult 0405 03E2 0406 03E2 0407 03E2 0408 03E2 ;decimal parser multiplication 0409 03E2 11 02 08 dp_10000_mult ldm dp_10000s 0410 03E5 0A 30 subim 30h ;ASCII for '0' 0411 03E7 14 04 04 jpz dp_10000_done 0412 03EA 10 10 ldi 10h ;hex low byte of 10,000 decimal 0413 03EC 00 00 08 addm dp_value 0414 03EF 12 00 08 stm dp_value 0415 03F2 10 27 ldi 27h ;hex high byte of 10,000 decimal 0416 03F4 01 01 08 adcm dp_value+1 0417 03F7 12 01 08 stm dp_value+1 0418 03FA 11 02 08 ldm dp_10000s 0419 03FD 1A dec 0420 03FE 12 02 08 stm dp_10000s 0421 0401 13 E2 03 jmp dp_10000_mult 0422 0404 dp_10000_done 0423 0404 11 03 08 dp_1000_mult ldm dp_1000s 0424 0407 0A 30 subim 30h ;ASCII for '0' 0425 0409 14 26 04 jpz dp_1000_done 0426 040C 10 E8 ldi 0e8h ;hex low byte of 1000 decimal 0427 040E 00 00 08 addm dp_value 0428 0411 12 00 08 stm dp_value 0429 0414 10 03 ldi 03h ;hex high byte of 1000 decimal 0430 0416 01 01 08 adcm dp_value+1 0431 0419 12 01 08 stm dp_value+1 0432 041C 11 03 08 ldm dp_1000s 0433 041F 1A dec 0434 0420 12 03 08 stm dp_1000s 0435 0423 13 04 04 jmp dp_1000_mult 0436 0426 dp_1000_done 0437 0426 11 04 08 dp_100_mult ldm dp_100s 0438 0429 0A 30 subim 30h ;ASCII for '0' 0439 042B 14 48 04 jpz dp_100_done 0440 042E 10 64 ldi 64h ;hex low byte of 100 decimal 0441 0430 00 00 08 addm dp_value 0442 0433 12 00 08 stm dp_value 0443 0436 10 00 ldi 00h ;hex high byte of 100 decimal 0444 0438 01 01 08 adcm dp_value+1 0445 043B 12 01 08 stm dp_value+1 0446 043E 11 04 08 ldm dp_100s 0447 0441 1A dec 0448 0442 12 04 08 stm dp_100s 0449 0445 13 26 04 jmp dp_100_mult 0450 0448 dp_100_done 0451 0448 11 05 08 dp_10_mult ldm dp_10s 0452 044B 0A 30 subim 30h ;ASCII for '0' 0453 044D 14 6A 04 jpz dp_10_done 0454 0450 10 0A ldi 0ah ;hex low byte of 10 decimal 0455 0452 00 00 08 addm dp_value 0456 0455 12 00 08 stm dp_value 0457 0458 10 00 ldi 00h ;hex high byte of 10 decimal 0458 045A 01 01 08 adcm dp_value+1 0459 045D 12 01 08 stm dp_value+1 0460 0460 11 05 08 ldm dp_10s 0461 0463 1A dec 0462 0464 12 05 08 stm dp_10s 0463 0467 13 48 04 jmp dp_10_mult 0464 046A dp_10_done 0465 046A 11 06 08 dp_1_mult ldm dp_1s 0466 046D 0A 30 subim 30h ;ASCII for '0' 0467 046F 00 00 08 addm dp_value 0468 0472 12 00 08 stm dp_value 0469 0475 10 00 ldi 00h ;hex high byte of 100 decimal 0470 0477 01 01 08 adcm dp_value+1 0471 047A 12 01 08 stm dp_value+1 0472 047D 0473 047D ;Set up byte counter and write ready string 0474 047D 11 00 08 ldm dp_value 0475 0480 12 08 08 stm bl_byte_counter 0476 0483 11 01 08 ldm dp_value+1 0477 0486 12 09 08 stm bl_byte_counter+1 0478 0489 11 CF 07 ldm bl_ready_str 0479 048C 12 34 08 stm ws_inst+1 0480 048F 11 D0 07 ldm bl_ready_str+1 0481 0492 12 35 08 stm ws_inst+2 0482 0495 call0(write_string) 0482 0495 0482 0495 11 A4 04 0482 0498 12 40 08 0482 049B 11 A5 04 0482 049E 12 41 08 0482 04A1 13 E7 05 0482 04A4 A6 04 0483 04A6 0484 04A6 ;Loop to get binary data and store 0485 04A6 17 03 bl_chk_loop: in 03h ;get status 0486 04A8 0C 02 andim 02h ;check RxRDY 0487 04AA 14 A6 04 jpz bl_chk_loop 0488 04AD 17 02 in 02h ;get binary from port 0489 04AF 13 2D 08 jmp bl_indexed_stm ;store in RAM 0490 04B2 11 2E 08 bl_back ldm bl_indexed_stm+1;increment pointer 0491 04B5 19 inc 0492 04B6 12 2E 08 stm bl_indexed_stm+1 0493 04B9 11 2F 08 ldm bl_indexed_stm+2 0494 04BC 09 00 adcim 0 0495 04BE 12 2F 08 stm bl_indexed_stm+2 0496 04C1 11 08 08 ldm bl_byte_counter ;decrement byte counter 0497 04C4 1A dec 0498 04C5 12 08 08 stm bl_byte_counter 0499 04C8 11 09 08 ldm bl_byte_counter+1 0500 04CB 0B 00 sbbim 0 0501 04CD 12 09 08 stm bl_byte_counter+1 0502 04D0 14 D6 04 jpz bl_low_zero ;check if byte counter = zero 0503 04D3 13 A6 04 jmp bl_chk_loop 0504 04D6 11 08 08 bl_low_zero ldm bl_byte_counter 0505 04D9 14 DF 04 jpz bl_done ;yes, done -- return to monitor 0506 04DC 13 A6 04 jmp bl_chk_loop ;no, get next byte 0507 04DF 13 98 00 bl_done jmp sm_warm 0508 04E2 0509 04E2 0510 04E2 0511 04E2 ;Routine to get address 0512 04E2 ;Not called as a subroutine, return jump by switch structure 0513 04E2 11 A1 07 get_address ldm addr_str 0514 04E5 12 34 08 stm ws_inst+1 0515 04E8 11 A2 07 ldm addr_str+1 0516 04EB 12 35 08 stm ws_inst+2 0517 04EE call0(write_string) 0517 04EE 0517 04EE 11 FD 04 0517 04F1 12 40 08 0517 04F4 11 FE 04 0517 04F7 12 41 08 0517 04FA 13 E7 05 0517 04FD FF 04 0518 04FF 0519 04FF ;Get hex input string for address 0520 04FF call0(get_line) 0520 04FF 0520 04FF 11 0E 05 0520 0502 12 40 08 0520 0505 11 0F 05 0520 0508 12 41 08 0520 050B 13 8D 05 0520 050E 10 05 0521 0510 0522 0510 ;Write newline 0523 0510 11 31 07 ldm new_line 0524 0513 12 34 08 stm ws_inst+1 0525 0516 11 32 07 ldm new_line+1 0526 0519 12 35 08 stm ws_inst+2 0527 051C call0(write_string) 0527 051C 0527 051C 11 2B 05 0527 051F 12 40 08 0527 0522 11 2C 05 0527 0525 12 41 08 0527 0528 13 E7 05 0527 052B 2D 05 0528 052D 0529 052D ;No error checking for length of string -- must be exactly 4 hex characters 0530 052D ;Memory address stored in address variable 0531 052D 11 80 08 ldm buffer ;first character 0532 0530 12 0A 08 stm char_pair 0533 0533 11 81 08 ldm buffer+1 ;second character 0534 0536 12 0B 08 stm char_pair+1 0535 0539 call1(hex_pair_to_byte) 0535 0539 0535 0539 11 48 05 0535 053C 12 43 08 0535 053F 11 49 05 0535 0542 12 44 08 0535 0545 13 54 06 0535 0548 4A 05 0536 054A 16 98 00 jpc sm_warm ;non-hex character detected, quit 0537 054D 12 0F 08 stm address+1 ;high byte of address 0538 0550 11 82 08 ldm buffer+2 ;third character 0539 0553 12 0A 08 stm char_pair 0540 0556 11 83 08 ldm buffer+3 ;fourth character 0541 0559 12 0B 08 stm char_pair+1 0542 055C call1(hex_pair_to_byte) 0542 055C 0542 055C 11 6B 05 0542 055F 12 43 08 0542 0562 11 6C 05 0542 0565 12 44 08 0542 0568 13 54 06 0542 056B 6D 05 0543 056D 16 98 00 jpc sm_warm ;non-hex character detected, quit 0544 0570 12 0E 08 stm address ;low byte of address 0545 0573 ;Switch for return jumps 0546 0573 11 11 08 ldm choice 0547 0576 0F 35 cmp '5' 0548 0578 16 18 03 jpc bl_addr_back 0549 057B 0F 34 cmp '4' 0550 057D 16 0C 02 jpc ld_addr_back 0551 0580 0F 33 cmp '3' 0552 0582 16 FA 01 jpc run_addr_back 0553 0585 0F 32 cmp '2' 0554 0587 16 E7 00 jpc d_addr_back 0555 058A 13 98 00 jmp sm_warm 0556 058D 0557 058D ;Get_line subroutine, call as level 0 0558 058D ;Gets a line from input, puts zero-terminated string in buffer 0559 058D ;Echos characters to screen, except terminating carriage return 0560 058D ;Address of buffer in buff_low and buff_high constants 0561 058D ;Uses RAM variable address instruction gl_indexed_stm 0562 058D ;length of input string returned in gl_str_len 0563 058D ;Returns when carriage return entered 0564 058D 0565 058D 10 00 get_line: ldi 0 0566 058F 12 07 08 stm gl_str_len ;string length 0567 0592 10 80 ldi buff_low ;low byte of buffer address 0568 0594 12 3A 08 stm gl_indexed_stm+1 0569 0597 10 08 ldi buff_high ;high byte of buffer address 0570 0599 12 3B 08 stm gl_indexed_stm+2 0571 059C 17 03 gl_chk_loop: in 03h ;get status 0572 059E 0C 02 andim 02h ;check RxRDY 0573 05A0 14 9C 05 jpz gl_chk_loop 0574 05A3 17 02 in 02h ;get char from port 0575 05A5 12 10 08 stm temp ;save character 0576 05A8 0A 0D subim 0dh ;is it a return character? 0577 05AA 14 BA 05 jpz gl_end_of_line ;yes, replace with a zero 0578 05AD 11 07 08 ldm gl_str_len ;no, increment string length 0579 05B0 19 inc 0580 05B1 12 07 08 stm gl_str_len 0581 05B4 11 10 08 ldm temp ;get back char 0582 05B7 13 BD 05 jmp gl_store_it ;place character in buffer 0583 05BA 12 10 08 gl_end_of_line: stm temp ;place zero in temp 0584 05BD 13 39 08 gl_store_it: jmp gl_indexed_stm ;store character in buffer 0585 05C0 11 10 08 gl_back: ldm temp ;check if end-of-line (temp = 0) 0586 05C3 14 E4 05 jpz gl_done ;yes, quit 0587 05C6 17 03 gl_out_loop: in 03h ;no, send char to screen 0588 05C8 0C 01 andim 01h ;check TxRDY 0589 05CA 14 C6 05 jpz gl_out_loop ;loop if not ready 0590 05CD 11 10 08 ldm temp 0591 05D0 18 02 out 02h ;output character to port 0592 05D2 11 3A 08 ldm gl_indexed_stm+1 ;increment indexing pointer 0593 05D5 19 inc 0594 05D6 12 3A 08 stm gl_indexed_stm+1 0595 05D9 11 3B 08 ldm gl_indexed_stm+2 0596 05DC 09 00 adcim 00h ;16-bit addition 0597 05DE 12 3B 08 stm gl_indexed_stm+2 0598 05E1 13 9C 05 jmp gl_chk_loop 0599 05E4 gl_done: ret0 0599 05E4 13 3F 08 0600 05E7 0601 05E7 ;Write_string subroutine, call as level 0 0602 05E7 ;Writes a zero-terminated string to screen at current cursor location 0603 05E7 ;Must set up address of string to be written in ws_inst+1 and ws_inst+2 0604 05E7 write_string: 0605 05E7 17 03 ws_chk_loop: in 03h ;get status 0606 05E9 0C 01 andim 01h ;check TxRDY 0607 05EB 14 E7 05 jpz ws_chk_loop 0608 05EE 13 33 08 jmp ws_inst ;get a character when port ready 0609 05F1 14 08 06 ws_back: jpz ws_done ;quit if end-of-string 0610 05F4 18 02 out 02h ;output character to port 0611 05F6 11 34 08 ldm ws_inst+1 ;indexing pointer 0612 05F9 19 inc 0613 05FA 12 34 08 stm ws_inst+1 0614 05FD 11 35 08 ldm ws_inst+2 0615 0600 09 00 adcim 00h ;16-bit addition 0616 0602 12 35 08 stm ws_inst+2 0617 0605 13 E7 05 jmp ws_chk_loop 0618 0608 ws_done: ret0 0618 0608 13 3F 08 0619 060B 0620 060B ;Subroutine hex_to word -- call as level 0 0621 060B ;Calls hex_pair_to_byte as level 1 0622 060B ;Get 16-bit word value from input string in buffer 0623 060B ;No error checking for length of string -- must be exactly 4 hex characters 0624 060B ;16-bit value placed in h2w_value 0625 060B 11 80 08 hex_to_word: ldm buffer ;first character 0626 060E 12 0A 08 stm char_pair 0627 0611 11 81 08 ldm buffer+1 ;second character 0628 0614 12 0B 08 stm char_pair+1 0629 0617 call1(hex_pair_to_byte) ;high-order byte 0629 0617 0629 0617 11 26 06 0629 061A 12 43 08 0629 061D 11 27 06 0629 0620 12 44 08 0629 0623 13 54 06 0629 0626 28 06 0630 0628 16 51 06 jpc h2w_done ;non-hex character detected, exit with carry set 0631 062B 12 0D 08 stm h2w_value+1 ;high byte of address 0632 062E 11 82 08 ldm buffer+2 ;third character 0633 0631 12 0A 08 stm char_pair 0634 0634 11 83 08 ldm buffer+3 ;fourth character 0635 0637 12 0B 08 stm char_pair+1 0636 063A call1(hex_pair_to_byte) ;low-order byte 0636 063A 0636 063A 11 49 06 0636 063D 12 43 08 0636 0640 11 4A 06 0636 0643 12 44 08 0636 0646 13 54 06 0636 0649 4B 06 0637 064B 16 51 06 jpc h2w_done ;exit with carry set if error 0638 064E 12 0C 08 stm h2w_value ;low byte of address 0639 0651 h2w_done ret0 0639 0651 13 3F 08 0640 0654 0641 0654 ;Subroutine to convert hex character pair to byte, call as level 1 0642 0654 ;Character pair in memory location char_pair, stored hi-low 0643 0654 ;Returns with byte in accumulator and carry flag clear if no error 0644 0654 ;Returns with character in accumulator and carry flag set if error 0645 0654 ;Calls char_to_nybble as level 2 subroutine 0646 0654 11 0A 08 hex_pair_to_byte: ldm char_pair ;high order character of pair 0647 0657 12 10 08 stm temp ;char_to_nybble needs char in TEMP 0648 065A call2(char_to_nybble) 0648 065A 0648 065A 11 69 06 0648 065D 12 46 08 0648 0660 11 6A 06 0648 0663 12 47 08 0648 0666 13 FF 06 0648 0669 6B 06 0649 066B 16 B0 06 jpc c2n_error 0650 066E 12 12 08 STM byte ;Will eventually contain the byte to load 0651 0671 12 10 08 STM temp ;Value to add 0652 0674 10 10 LDI 10H ;Multiply x 16 to shift into high-order nybble 0653 0676 12 13 08 STM counter 0654 0679 11 13 08 MULTLOOP: LDM counter 0655 067C 1A DEC 0656 067D 14 8F 06 JPZ GET_LO ;Have added 16 times, done 0657 0680 12 13 08 STM counter 0658 0683 11 10 08 LDM temp ;Original nybble 0659 0686 00 12 08 ADD byte ;Add to BYTE and store 0660 0689 12 12 08 STM byte 0661 068C 13 79 06 JMP MULTLOOP ;Keep adding 0662 068F 11 0B 08 GET_LO: ldm char_pair+1 0663 0692 12 10 08 stm temp 0664 0695 call2(char_to_nybble) 0664 0695 0664 0695 11 A4 06 0664 0698 12 46 08 0664 069B 11 A5 06 0664 069E 12 47 08 0664 06A1 13 FF 06 0664 06A4 A6 06 0665 06A6 16 B0 06 jpc c2n_error 0666 06A9 00 12 08 ADD byte ;Combine with hi nybble stored in BYTE 0667 06AC 1C ccf ;in case addition changed it 0668 06AD 13 B1 06 JMP c2b_done ;Done, no error 0669 06B0 1B c2n_error: scf 0670 06B1 c2b_done: ret1 0670 06B1 13 42 08 0671 06B4 0672 06B4 ;Subroutine to convert byte to hex character pair, call as level 0 0673 06B4 ;Gets byte from byte variable 0674 06B4 ;Returns with character pair in memory location char_pair, stored hi-low 0675 06B4 ; 0676 06B4 byte_to_hex_pair: 0677 06B4 11 12 08 ldm byte 0678 06B7 0C F0 andim 0f0h ;dealing with high nybble 0679 06B9 12 10 08 stm temp 0680 06BC 10 00 ldi 00h ;prepare to shift down (divide by 16) 0681 06BE 12 13 08 stm counter 0682 06C1 11 10 08 b2h_divide: ldm temp 0683 06C4 0A 10 subim 16 0684 06C6 16 D6 06 jpc b2h_cont ;continue if nybble >=0 0685 06C9 11 13 08 ldm counter ;hi-nybble now in low position 0686 06CC 0F 0A cmp 10 ;is value <10? 0687 06CE 16 E3 06 jpc b2h_hi_A2F ;yes, jump and convert to char 0688 06D1 08 30 addim 30h ;no, convert to char 0689 06D3 13 E5 06 jmp b2h_store_hi 0690 06D6 12 10 08 b2h_cont: stm temp 0691 06D9 11 13 08 ldm counter 0692 06DC 19 inc 0693 06DD 12 13 08 stm counter 0694 06E0 13 C1 06 jmp b2h_divide 0695 06E3 08 37 b2h_hi_A2F: addim 37h 0696 06E5 12 0A 08 b2h_store_hi: stm char_pair ;hi-order hex char 0697 06E8 11 12 08 ldm byte 0698 06EB 0C 0F andim 0fh ;dealing with low-order nybble 0699 06ED 0F 0A cmp 10 ;is value <10? 0700 06EF 16 F7 06 jpc b2h_lo_A2F ;yes, jump and convert to char 0701 06F2 08 30 addim 30h ;no, convert to char 0702 06F4 13 F9 06 jmp b2h_store_lo 0703 06F7 08 37 b2h_lo_A2F: addim 37h 0704 06F9 12 0B 08 b2h_store_lo: stm char_pair+1 ;now char pair is in variable 0705 06FC ret0 0705 06FC 13 3F 08 0706 06FF 0707 06FF 0708 06FF ;Subroutine to convert hex char to nybble, call as level 2 0709 06FF ;Checks for validity of char, 0-9 and A-F (upper case only) 0710 06FF ;Carry flag set on exit if error 0711 06FF ;Carry flag clear if character valid 0712 06FF ;Call with char in temp 0713 06FF ;Exits with nybble in lower half of accumulator if no error 0714 06FF ;Original character in accumulator if error 0715 06FF 0716 06FF 11 10 08 char_to_nybble: ldm temp ;Get character 0717 0702 0F 30 cmp 30H ;Lower limit of hex characters 0718 0704 16 0A 07 jpc c2n_next ;Char >= 30H, possibly valid 0719 0707 13 2A 07 jmp invalid ;Char < 30H, invalid hex char 0720 070A 0F 47 c2n_next: cmp 47h ;ASCII for "G" 0721 070C 16 2A 07 jpc invalid ;Char is G or greater, invalid 0722 070F 0F 41 cmp 41h ;ASCII for "A" 0723 0711 16 1C 07 jpc validAF ;Char is valid A-F 0724 0714 0F 3A cmp 3Ah ;ASCII for ":" 0725 0716 16 2A 07 jpc invalid ;Char is ":" or greater, but < "A", invalid 0726 0719 13 24 07 jmp valid09 ;Char is valid 0-9 0727 071C 0C 0F validAF: andim 0fh ;Mask off high bits 0728 071E 08 09 addim 9 ;Adjust ASCII to binary value 0729 0720 1C ccf ;exit no error 0730 0721 ret2 0730 0721 13 45 08 0731 0724 0C 0F valid09: andim 0fh ;Mask off high bits 0732 0726 1C ccf ;exit no error 0733 0727 ret2 0733 0727 13 45 08 0734 072A 11 10 08 invalid: ldm temp ;put char in accumulator 0735 072D 1B scf ;Set carry flag 0736 072E ret2 0736 072E 13 45 08 0737 0731 ;String constants 0738 0731 33 07 new_line .dw $+2 0739 0733 0D 0A 00 .db 0dh,0ah,0 0740 0736 38 07 sm_greeting: .dw $+2 0741 0738 0D 0A .db 0dh,0ah 0742 073A 43505576696C .text "CPUville 8-bit processor system monitor v.1" 0742 0740 6C6520382D6269742070726F636573736F722073797374656D206D6F6E69746F7220762E31 0743 0765 0D 0A 00 .db 0dh,0ah,0 0744 0768 6A 07 sm_prompt .dw $+2 0745 076A 0D 0A .db 0dh,0ah 0746 076C 456E74657220 .text "Enter number: 1=restart 2=dump 3=run 4=load 5=bload " 0746 0772 6E756D6265723A20313D7265737461727420323D64756D7020333D72756E20343D6C6F616420353D626C6F616420 0747 07A0 00 .db 0 0748 07A1 A3 07 addr_str .dw $+2 0749 07A3 0D 0A .db 0dh,0ah 0750 07A5 416464726573 .text Address (hex): 0750 07AB 732028686578293A20 0751 07B4 00 .db 0 0752 07B5 B7 07 bytes_str .dw $+2 0753 07B7 0D 0A .db 0dh,0ah 0754 07B9 427974657320 .text Bytes to load (dec): 0754 07BF 746F206C6F61642028646563293A20 0755 07CE 00 .db 0 0756 07CF D1 07 bl_ready_str .dw $+2 0757 07D1 0D 0A .db 0dh,0ah 0758 07D3 52656164792C .text Ready, start transfer 0758 07D9 207374617274207472616E73666572 0759 07E8 0D 0A 00 .db 0dh,0ah,0 0760 07EB 0761 07EB ;The following section contains labels for RAM variables and other structures 0762 0800 .org 0800h ;Start of RAM 0763 0800 ;RAM Variables 0764 0800 00 00 dp_value .dw 0000h 0765 0802 00 dp_10000s .db 00h 0766 0803 00 dp_1000s .db 00h 0767 0804 00 dp_100s .db 00h 0768 0805 00 dp_10s .db 00h 0769 0806 00 dp_1s .db 00h 0770 0807 00 gl_str_len .db 00h 0771 0808 00 00 bl_byte_counter .dw 0000h 0772 080A 00 00 char_pair .dw 0000h 0773 080C 00 00 h2w_value .dw 0000h 0774 080E 00 00 address .dw 0000h 0775 0810 00 temp .db 00h 0776 0811 00 choice .db 00h 0777 0812 00 byte .db 00h 0778 0813 00 counter .db 00h 0779 0814 00 line_counter .db 00h 0780 0815 00 char_count .db 00h 0781 0816 00 byte_counter .db 00h 0782 0817 00 nybble_counter .db 00h 0783 0818 0784 0818 ;RAM instructions with variable address (must initialize opcode when monitor is in ROM) 0785 0818 ;Jump instruction for run routine, must be in RAM 0786 0818 13 00 00 run_jump jmp 0000h 0787 081B ;Indexed load for load routine, must be in RAM 0788 081B 12 00 00 ld_indexed_stm stm 0000h 0789 081E 13 00 03 jmp ld_stm_back 0790 0821 ;Indexed load and store instructions for dump, must be in RAM 0791 0821 11 00 00 d_indexed_ldm ldm 0000h 0792 0824 13 59 01 jmp d_ldm_back 0793 0827 12 00 00 d_indexed_stm stm 0000h 0794 082A 13 78 01 jmp d_stm_back 0795 082D ;Indexed store instruction for binary loader, must be in RAM 0796 082D 12 00 00 bl_indexed_stm: stm 0000h 0797 0830 13 B2 04 jmp bl_back 0798 0833 ;Indexed load instruction for write_string, must be in RAM 0799 0833 11 00 00 ws_inst: ldm 0000h 0800 0836 13 F1 05 jmp ws_back 0801 0839 ;Indexed store instruction for get_line, must be in RAM 0802 0839 12 00 00 gl_indexed_stm: stm 0000h 0803 083C 13 C0 05 jmp gl_back 0804 083F ;Return instruction for level 0 call macros, must be in RAM 0805 083F 13 00 00 return_jump0: jmp 0000h 0806 0842 ;Return instruction for level 1 call macros, must be in RAM 0807 0842 13 00 00 return_jump1: jmp 0000h 0808 0845 ;Return instruction for level 2 call macros, must be in RAM 0809 0845 13 00 00 return_jump2: jmp 0000h 0810 0848 0811 0848 return: .set 0000h ;assembler needs variable label set back to original value 0812 0848 .end 0813 0848 0814 0848 0815 0848 0816 0848 0817 0848 0818 0848 0819 0848 tasm: Number of errors = 0