1 |
22 |
dilbert57 |
Assembler release DWC_2.0 version 2.11
|
2 |
|
|
May 6, 2004 (c) Motorola (free ware)
|
3 |
|
|
0001 * 6809 Debug monitor for use with NOICE09
|
4 |
|
|
0002 *
|
5 |
|
|
0003 * Copyright (c) 1992-2006 by John Hartman
|
6 |
|
|
0004 *
|
7 |
|
|
0005 * Modification History:
|
8 |
|
|
0006 * 14-Jun-93 JLH release version
|
9 |
|
|
0007 * 24-Aug-93 JLH bad constant for COMBUF length compare
|
10 |
|
|
0008 * 25-Feb-98 JLH assemble with either Motorola or Dunfield
|
11 |
|
|
0009 * 1-May-06 JLH slight cleanup
|
12 |
|
|
0010 * 4-Jul-06 JEK Modified for System09 ACIA at $E000/$E001
|
13 |
|
|
0011 * 2K monitor RAM at $F000 - $F7FF
|
14 |
|
|
0012 * Allocated 1536 bytes ($600) for user stack.
|
15 |
|
|
0013 * disables watchdog timer
|
16 |
|
|
0014 *
|
17 |
|
|
0015 *============================================================================
|
18 |
|
|
0016 *
|
19 |
|
|
0017 * To customize for a given target, you must change code in the
|
20 |
|
|
0018 * hardware equates, the string TSTG, and the routines RESET and REWDT.
|
21 |
|
|
0019 * You may or may not need to change GETCHAR, PUTCHAR, depending on
|
22 |
|
|
0020 * how peculiar your UART is.
|
23 |
|
|
0021 *
|
24 |
|
|
0022 * This file has been assembled with the Motorola Freeware assembler
|
25 |
|
|
0023 * available from the Motorola Freeware BBS and elsewhere.
|
26 |
|
|
0024 * BUT: you must first "comment out" the conditionals as required,
|
27 |
|
|
0025 * because the Motorola assemblers do not have any IFEQ/ELSE/ENDIF
|
28 |
|
|
0026 *
|
29 |
|
|
0027 * This file may also be assembled with the Dunfield assembler
|
30 |
|
|
0028 *
|
31 |
|
|
0029 * To add mapped memory support:
|
32 |
|
|
0030 * 1) Define map port MAPREG here
|
33 |
|
|
0031 * 2) Define or import map port RAM image MAPIMG here if MAPREG is
|
34 |
|
|
0032 * write only. (The application code must update MAPIMG before
|
35 |
|
|
0033 * outputing to MAPREG)
|
36 |
|
|
0034 * 3) Search for and modify MAPREG, MAPIMG, and REG_PAGE usage below
|
37 |
|
|
0035 * 4) In TSTG below edit "LOW AND HIGH LIMIT OF MAPPED MEM"
|
38 |
|
|
0036 * to appropriate range (typically 4000H to 07FFFH for two-bit MMU)
|
39 |
|
|
0037 *
|
40 |
|
|
0038 *============================================================================
|
41 |
|
|
0039 *
|
42 |
|
|
0040 * I/O equates for Heng's ROM emulator (set true if used)
|
43 |
|
|
0041 ***ROMEM SET 1
|
44 |
|
|
0042 *
|
45 |
|
|
0043 *============================================================================
|
46 |
|
|
0044 * HARDWARE PLATFORM CUSTOMIZATIONS
|
47 |
|
|
0045 *
|
48 |
|
|
0046 *RAM_START EQU $D800 START OF MONITOR RAM
|
49 |
|
|
0047 F000 RAM_START EQU $F000 START OF MONITOR RAM
|
50 |
|
|
0048 FC00 ROM_START EQU $FC00 START OF MONITOR CODE
|
51 |
|
|
0049 FFF0 HARD_VECT EQU $FFF0 START OF HARDWARE VECTORS
|
52 |
|
|
0050
|
53 |
|
|
0051 *============================================================================
|
54 |
|
|
0052 * Equates for memory mapped 16450 serial port on Heng's ROM emulator board
|
55 |
|
|
0053 *;* IFEQ ROMEM,1
|
56 |
|
|
0054 *
|
57 |
|
|
0055 *S16450 equ $A000 base of 16450 UART
|
58 |
|
|
0056 *RXR equ 0 Receiver buffer register
|
59 |
|
|
0057 *TXR equ 0 Transmitter buffer register
|
60 |
|
|
0058 *IER equ 1 Interrupt enable register
|
61 |
|
|
0059 *LCR equ 3 Line control register
|
62 |
|
|
0060 *MCR equ 4 Modem control register
|
63 |
|
|
0061 *DTR equ 1 Bit equate used to control status LED
|
64 |
|
|
0062 *LSR equ 5 Line status register
|
65 |
|
|
0063 *
|
66 |
|
|
0064 * Define monitor serial port
|
67 |
|
|
0065 *SER_STATUS EQU S16450+LSR
|
68 |
|
|
0066 *SER_RXDATA EQU S16450+RXR
|
69 |
|
|
0067 *SER_TXDATA EQU S16450+TXR
|
70 |
|
|
0068 *RXRDY EQU $01 BIT MASK FOR RX BUFFER FULL
|
71 |
|
|
0069 *TXRDY EQU $20 BIT MASK FOR TX BUFFER EMPTY
|
72 |
|
|
0070 *;* ELSE
|
73 |
|
|
0071 *
|
74 |
|
|
0072 * Put you UART equates here
|
75 |
|
|
0073 E000 SER_STATUS EQU $E000
|
76 |
|
|
0074 E001 SER_RXDATA EQU $E001
|
77 |
|
|
0075 E001 SER_TXDATA EQU $E001
|
78 |
|
|
0076 0001 RXRDY EQU $01
|
79 |
|
|
0077 0002 TXRDY EQU $02
|
80 |
|
|
0078 *
|
81 |
|
|
0079 *;* ENDIF
|
82 |
|
|
0080 *
|
83 |
|
|
0081 * Watchdog timer (if any) See REWDT for use
|
84 |
|
|
0082 *WDT EQU $207
|
85 |
|
|
0083 *
|
86 |
|
|
0084 * Condition code bits
|
87 |
|
|
0085 0001 C EQU 1
|
88 |
|
|
0086 000A I EQU 10H
|
89 |
|
|
0087 0028 F EQU 40H
|
90 |
|
|
0088 0050 E EQU 80H
|
91 |
|
|
0089 *
|
92 |
|
|
0090 *============================================================================
|
93 |
|
|
0091 * RAM definitions:
|
94 |
|
|
0092 F000 ORG RAM_START
|
95 |
|
|
0093 *
|
96 |
|
|
0094 * RAM interrupt vectors (first in SEG for easy addressing, else move to
|
97 |
|
|
0095 * their own SEG)
|
98 |
|
|
0096 0008 NVEC EQU 8 number of vectors
|
99 |
|
|
0097 F000 RAMVEC RMB 2*NVEC
|
100 |
|
|
0098 *
|
101 |
|
|
0099 * Initial user stack
|
102 |
|
|
0100 * (Size and location is user option)
|
103 |
|
|
0101 * RMB 64
|
104 |
|
|
0102 F010 RMB $600
|
105 |
|
|
0103 INITSTACK
|
106 |
|
|
0104 *
|
107 |
|
|
0105 * Monitor stack
|
108 |
|
|
0106 * (Calculated use is at most 7 bytes. Leave plenty of spare)
|
109 |
|
|
0107 F610 RMB 16
|
110 |
|
|
0108 MONSTACK
|
111 |
|
|
0109 *
|
112 |
|
|
0110 * Target registers: order must match that in TRGHC11.C
|
113 |
|
|
0111 TASK_REGS
|
114 |
|
|
0112 F620 REG_STATE RMB 1
|
115 |
|
|
0113 F621 REG_PAGE RMB 1
|
116 |
|
|
0114 F622 REG_SP RMB 2
|
117 |
|
|
0115 F624 REG_U RMB 2
|
118 |
|
|
0116 F626 REG_Y RMB 2
|
119 |
|
|
0117 F628 REG_X RMB 2
|
120 |
|
|
0118 F62A REG_B RMB 1 B BEFORE A, SO D IS LEAST SIG. FIRST
|
121 |
|
|
0119 F62B REG_A RMB 1
|
122 |
|
|
0120 F62C REG_DP RMB 1
|
123 |
|
|
0121 F62D REG_CC RMB 1
|
124 |
|
|
0122 F62E REG_PC RMB 2
|
125 |
|
|
0123 0010 TASK_REG_SZ EQU *-TASK_REGS
|
126 |
|
|
0124 *
|
127 |
|
|
0125 * Communications buffer
|
128 |
|
|
0126 * (Must be at least as long as TASK_REG_SZ. At least 19 bytes recommended.
|
129 |
|
|
0127 * Larger values may improve speed of NoICE memory move commands.)
|
130 |
|
|
0128 0080 COMBUF_SIZE EQU 128 DATA SIZE FOR COMM BUFFER
|
131 |
|
|
0129 F630 COMBUF RMB 2+COMBUF_SIZE+1 BUFFER ALSO HAS FN, LEN, AND CHECK
|
132 |
|
|
0130 *
|
133 |
|
|
0131 F6B3 RAM_END EQU * ADDRESS OF TOP+1 OF RAM
|
134 |
|
|
0132 *
|
135 |
|
|
0133 *===========================================================================
|
136 |
|
|
0134 FC00 ORG ROM_START
|
137 |
|
|
0135 *
|
138 |
|
|
0136 * Power on reset
|
139 |
|
|
0137 RESET
|
140 |
|
|
0138 *
|
141 |
|
|
0139 * Set CPU mode to safe state
|
142 |
|
|
0140 FC00 1A 32 ORCC #I+F INTERRUPTS OFF
|
143 |
|
|
0141 FC02 10 CE F6 20 LDS #MONSTACK CLEAN STACK IS HAPPY STACK
|
144 |
|
|
0142 *
|
145 |
|
|
0143 *----------------------------------------------------------------------------
|
146 |
|
|
0144 *;* IFEQ ROMEM,1
|
147 |
|
|
0145 *
|
148 |
|
|
0146 * Initialize S16450 UART on ROM emulator
|
149 |
|
|
0147 *
|
150 |
|
|
0148 * Delay here in case the UART has not come out of reset yet.
|
151 |
|
|
0149 FC06 8E 00 00 LDX #0
|
152 |
|
|
0150 FC09 30 1F LOP LEAX -1,X DELAY FOR SLOW RESETTING UART
|
153 |
|
|
0151 FC0B 12 NOP
|
154 |
|
|
0152 FC0C 12 NOP
|
155 |
|
|
0153 FC0D 26 FA BNE LOP
|
156 |
|
|
0154 *
|
157 |
|
|
0155 * access baud generator, no parity, 1 stop bit, 8 data bits
|
158 |
|
|
0156 * LDA #$83
|
159 |
|
|
0157 * STA S16450+LCR
|
160 |
|
|
0158 *
|
161 |
|
|
0159 * fixed baud rate of 19200: crystal is 3.686400 Mhz.
|
162 |
|
|
0160 * Divisor is 3,686400/(16*baud)
|
163 |
|
|
0161 * LDA #12 fix at 19.2 kbaud
|
164 |
|
|
0162 * STA S16450+RXR lsb
|
165 |
|
|
0163 * LDA #0
|
166 |
|
|
0164 * STA S16450+RXR+1 msb=0
|
167 |
|
|
0165 *
|
168 |
|
|
0166 * access data registers, no parity, 1 stop bits, 8 data bits
|
169 |
|
|
0167 * LDA #$03
|
170 |
|
|
0168 * STA S16450+LCR
|
171 |
|
|
0169 *
|
172 |
|
|
0170 * no loopback, OUT2 on, OUT1 on, RTS on, DTR (LED) on
|
173 |
|
|
0171 * LDA #$0F
|
174 |
|
|
0172 * STA S16450+MCR
|
175 |
|
|
0173 *
|
176 |
|
|
0174 * disable all interrupts: modem, receive error, transmit, and receive
|
177 |
|
|
0175 * LDA #$00
|
178 |
|
|
0176 * STA S16450+IER
|
179 |
|
|
0177 *
|
180 |
|
|
0178 *;* ELSE
|
181 |
|
|
0179 *
|
182 |
|
|
0180 * Initialize your UART here
|
183 |
|
|
0181 FC0F 86 03 LDA #$03 Reset ACIA
|
184 |
|
|
0182 FC11 B7 E0 00 STA SER_STATUS
|
185 |
|
|
0183 FC14 86 11 LDA #$11 8 data 2 stop no parity
|
186 |
|
|
0184 FC16 B7 E0 00 STA SER_STATUS
|
187 |
|
|
0185 FC19 7D E0 01 TST SER_RXDATA
|
188 |
|
|
0186 *;* ENDIF
|
189 |
|
|
0187 *
|
190 |
|
|
0188 *----------------------------------------------------------------------------
|
191 |
|
|
0189 *
|
192 |
|
|
0190 * Initialize RAM interrupt vectors
|
193 |
|
|
0191 FC1C 10 8E FC AC LDY #INT_ENTRY ADDRESS OF DEFAULT HANDLER
|
194 |
|
|
0192 FC20 8E F0 00 LDX #RAMVEC POINTER TO RAM VECTORS
|
195 |
|
|
0193 FC23 C6 08 LDB #NVEC NUMBER OF VECTORS
|
196 |
|
|
0194 FC25 10 AF 81 RES10 STY ,X++ SET VECTOR
|
197 |
|
|
0195 FC28 5A DECB
|
198 |
|
|
0196 FC29 26 FA BNE RES10
|
199 |
|
|
0197 *
|
200 |
|
|
0198 * Initialize user registers
|
201 |
|
|
0199 FC2B CC F6 10 LDD #INITSTACK
|
202 |
|
|
0200 FC2E B7 F6 23 STA REG_SP+1 INIT USER'S STACK POINTER MSB
|
203 |
|
|
0201 FC31 F7 F6 22 STB REG_SP LSB
|
204 |
|
|
0202 *
|
205 |
|
|
0203 FC34 CC 00 00 LDD #0
|
206 |
|
|
0204 FC37 FD F6 2E STD REG_PC
|
207 |
|
|
0205 FC3A B7 F6 2B STA REG_A
|
208 |
|
|
0206 FC3D B7 F6 2A STA REG_B
|
209 |
|
|
0207 FC40 B7 F6 2C STA REG_DP
|
210 |
|
|
0208 FC43 FD F6 28 STD REG_X
|
211 |
|
|
0209 FC46 FD F6 26 STD REG_Y
|
212 |
|
|
0210 FC49 FD F6 24 STD REG_U
|
213 |
|
|
0211 FC4C B7 F6 20 STA REG_STATE initial state is "RESET"
|
214 |
|
|
0212 *
|
215 |
|
|
0213 * Initialize memory paging variables and hardware (if any)
|
216 |
|
|
0214 FC4F B7 F6 21 STA REG_PAGE initial page is zero
|
217 |
|
|
0215 *;;; STA MAPIMG
|
218 |
|
|
0216 *;;; STA MAPREG set hardware map
|
219 |
|
|
0217 *
|
220 |
|
|
0218 FC52 86 82 LDA #E+I+F state "all regs pushed", no ints
|
221 |
|
|
0219 FC54 B7 F6 2D STA REG_CC
|
222 |
|
|
0220 *
|
223 |
|
|
0221 * Set function code for "GO". Then if we reset after being told to
|
224 |
|
|
0222 * GO, we will come back with registers so user can see the crash
|
225 |
|
|
0223 FC57 86 FA LDA #FN_RUN_TARG
|
226 |
|
|
0224 FC59 B7 F6 30 STA COMBUF
|
227 |
|
|
0225 FC5C 7E FD D1 JMP RETURN_REGS DUMP REGS, ENTER MONITOR
|
228 |
|
|
0226 *
|
229 |
|
|
0227 *===========================================================================
|
230 |
|
|
0228 * Get a character to A
|
231 |
|
|
0229 *
|
232 |
|
|
0230 * Return A=char, CY=0 if data received
|
233 |
|
|
0231 * CY=1 if timeout (0.5 seconds)
|
234 |
|
|
0232 *
|
235 |
|
|
0233 * Uses 6 bytes of stack including return address
|
236 |
|
|
0234 *
|
237 |
|
|
0235 GETCHAR
|
238 |
|
|
0236 FC5F 34 10 PSHS X
|
239 |
|
|
0237 FC61 8E 00 00 LDX #0 LONG TIMEOUT
|
240 |
|
|
0238 FC64 BD FC 8E GC10 JSR REWDT PREVENT WATCHDOG TIMEOUT
|
241 |
|
|
0239 FC67 30 1F LEAX -1,X
|
242 |
|
|
0240 FC69 27 0D BEQ GC90 EXIT IF TIMEOUT
|
243 |
|
|
0241 FC6B B6 E0 00 LDA SER_STATUS READ DEVICE STATUS
|
244 |
|
|
0242 FC6E 84 01 ANDA #RXRDY
|
245 |
|
|
0243 FC70 27 F2 BEQ GC10 NOT READY YET.
|
246 |
|
|
0244 *
|
247 |
|
|
0245 * Data received: return CY=0. data in A
|
248 |
|
|
0246 FC72 4F CLRA CY=0
|
249 |
|
|
0247 FC73 B6 E0 01 LDA SER_RXDATA READ DATA
|
250 |
|
|
0248 FC76 35 90 PULS X,PC
|
251 |
|
|
0249 *
|
252 |
|
|
0250 * Timeout: return CY=1
|
253 |
|
|
0251 FC78 1A 01 GC90 ORCC #C CY=1
|
254 |
|
|
0252 FC7A 35 90 PULS X,PC
|
255 |
|
|
0253 *
|
256 |
|
|
0254 *===========================================================================
|
257 |
|
|
0255 * Output character in A
|
258 |
|
|
0256 *
|
259 |
|
|
0257 * Uses 5 bytes of stack including return address
|
260 |
|
|
0258 *
|
261 |
|
|
0259 PUTCHAR
|
262 |
|
|
0260 FC7C 34 02 PSHS A
|
263 |
|
|
0261 FC7E BD FC 8E PC10 JSR REWDT PREVENT WATCHDOG TIMEOUT
|
264 |
|
|
0262 FC81 B6 E0 00 LDA SER_STATUS CHECK TX STATUS
|
265 |
|
|
0263 FC84 84 02 ANDA #TXRDY RX READY ?
|
266 |
|
|
0264 FC86 27 F6 BEQ PC10
|
267 |
|
|
0265 FC88 35 02 PULS A
|
268 |
|
|
0266 FC8A B7 E0 01 STA SER_TXDATA TRANSMIT CHAR.
|
269 |
|
|
0267 FC8D 39 RTS
|
270 |
|
|
0268 *
|
271 |
|
|
0269 *======================================================================
|
272 |
|
|
0270 *
|
273 |
|
|
0271 * RESET WATCHDOG TIMER. MUST BE CALLED AT LEAST ONCE EVERY LITTLE WHILE
|
274 |
|
|
0272 * OR COP INTERRUPT WILL OCCUR
|
275 |
|
|
0273 *
|
276 |
|
|
0274 * Uses 2 bytes of stack including return address
|
277 |
|
|
0275 *
|
278 |
|
|
0276 FC8E 4F REWDT CLRA
|
279 |
|
|
0277 * STA WDT
|
280 |
|
|
0278 FC8F 4C INCA
|
281 |
|
|
0279 * STA WDT CU-style WDT: must leave bit high
|
282 |
|
|
0280 FC90 39 RTS
|
283 |
|
|
0281 *
|
284 |
|
|
0282 *======================================================================
|
285 |
|
|
0283 * Response string for GET TARGET STATUS request
|
286 |
|
|
0284 * Reply describes target:
|
287 |
|
|
0285 FC91 05 TSTG FCB 5 2: PROCESSOR TYPE = 6809
|
288 |
|
|
0286 FC92 80 FCB COMBUF_SIZE 3: SIZE OF COMMUNICATIONS BUFFER
|
289 |
|
|
0287 FC93 00 FCB 0 4: NO TASKING SUPPORT
|
290 |
|
|
0288 FC94 00 00 00 00 FDB 0,0 5-8: LOW AND HIGH LIMIT OF MAPPED MEM (NONE)
|
291 |
|
|
0289 FC98 01 FCB B1-B0 9: BREAKPOINT INSTR LENGTH
|
292 |
|
|
0290 FC99 3F B0 SWI 10: BREAKPOINT INSTRUCTION
|
293 |
|
|
0291 FC9A 36 38 30 39 20 6D B1 FCC '6809 monitor V1.0' DESCRIPTION, ZERO
|
294 |
|
|
6F 6E 69 74 6F 72
|
295 |
|
|
20 56 31 2E 30
|
296 |
|
|
0292 FCAB 00 FCB 0
|
297 |
|
|
0293 001B TSTG_SIZE EQU *-TSTG SIZE OF STRING
|
298 |
|
|
0294 *
|
299 |
|
|
0295 *======================================================================
|
300 |
|
|
0296 * HARDWARE PLATFORM INDEPENDENT EQUATES AND CODE
|
301 |
|
|
0297 *
|
302 |
|
|
0298 * Communications function codes.
|
303 |
|
|
0299 00FF FN_GET_STAT EQU $FF reply with device info
|
304 |
|
|
0300 00FE FN_READ_MEM EQU $FE reply with data
|
305 |
|
|
0301 00FD FN_WRITE_M EQU $FD reply with status (+/-)
|
306 |
|
|
0302 00FC FN_READ_RG EQU $FC reply with registers
|
307 |
|
|
0303 00FB FN_WRITE_RG EQU $FB reply with status
|
308 |
|
|
0304 00FA FN_RUN_TARG EQU $FA reply (delayed) with registers
|
309 |
|
|
0305 00F9 FN_SET_BYTE EQU $F9 reply with data (truncate if error)
|
310 |
|
|
0306 00F8 FN_IN EQU $F8 input from port
|
311 |
|
|
0307 00F7 FN_OUT EQU $F7 output to port
|
312 |
|
|
0308 *
|
313 |
|
|
0309 00F7 FN_MIN EQU $F7 MINIMUM RECOGNIZED FUNCTION CODE
|
314 |
|
|
0310 00F0 FN_ERROR EQU $F0 error reply to unknown op-code
|
315 |
|
|
0311 *
|
316 |
|
|
0312 *===========================================================================
|
317 |
|
|
0313 * Common handler for default interrupt handlers
|
318 |
|
|
0314 * Enter with A=interrupt code = processor state
|
319 |
|
|
0315 * All registers stacked, PC=next instruction
|
320 |
|
|
0316 INT_ENTRY
|
321 |
|
|
0317 FCAC B7 F6 20 STA REG_STATE SAVE STATE
|
322 |
|
|
0318 *
|
323 |
|
|
0319 * Save registers from stack to reg block for return to master
|
324 |
|
|
0320 * Host wants least significant bytes first, so flip as necessary
|
325 |
|
|
0321 FCAF 35 02 PULS A
|
326 |
|
|
0322 FCB1 B7 F6 2D STA REG_CC CONDITION CODES
|
327 |
|
|
0323 FCB4 35 02 PULS A
|
328 |
|
|
0324 FCB6 B7 F6 2B STA REG_A A
|
329 |
|
|
0325 FCB9 35 02 PULS A
|
330 |
|
|
0326 FCBB B7 F6 2A STA REG_B B
|
331 |
|
|
0327 FCBE 35 02 PULS A
|
332 |
|
|
0328 FCC0 B7 F6 2C STA REG_DP DP
|
333 |
|
|
0329 FCC3 35 06 PULS D
|
334 |
|
|
0330 FCC5 B7 F6 29 STA REG_X+1 MSB X
|
335 |
|
|
0331 FCC8 F7 F6 28 STB REG_X LSB X
|
336 |
|
|
0332 FCCB 35 06 PULS D
|
337 |
|
|
0333 FCCD B7 F6 27 STA REG_Y+1 MSB Y
|
338 |
|
|
0334 FCD0 F7 F6 26 STB REG_Y LSB Y
|
339 |
|
|
0335 FCD3 35 06 PULS D
|
340 |
|
|
0336 FCD5 B7 F6 25 STA REG_U+1 MSB U
|
341 |
|
|
0337 FCD8 F7 F6 24 STB REG_U LSB U
|
342 |
|
|
0338 *
|
343 |
|
|
0339 * If this is a breakpoint (state = 1), then back up PC to point at SWI
|
344 |
|
|
0340 FCDB 35 10 PULS X PC AFTER INTERRUPT
|
345 |
|
|
0341 FCDD B6 F6 20 LDA REG_STATE
|
346 |
|
|
0342 FCE0 81 01 CMPA #1
|
347 |
|
|
0343 FCE2 26 02 BNE NOTBP BR IF NOT A BREAKPOINT
|
348 |
|
|
0344 FCE4 30 1F LEAX -1,X ELSE BACK UP TO POINT AT SWI LOCATION
|
349 |
|
|
0345 FCE6 1F 10 NOTBP TFR X,D TRANSFER PC TO D
|
350 |
|
|
0346 FCE8 B7 F6 2F STA REG_PC+1 MSB
|
351 |
|
|
0347 FCEB F7 F6 2E STB REG_PC LSB
|
352 |
|
|
0348 FCEE 7E FE 37 JMP ENTER_MON REG_PC POINTS AT POST-INTERRUPT OPCODE
|
353 |
|
|
0349 *
|
354 |
|
|
0350 *===========================================================================
|
355 |
|
|
0351 * Main loop wait for command frame from master
|
356 |
|
|
0352 *
|
357 |
|
|
0353 * Uses 6 bytes of stack including return address
|
358 |
|
|
0354 *
|
359 |
|
|
0355 FCF1 10 CE F6 20 MAIN LDS #MONSTACK CLEAN STACK IS HAPPY STACK
|
360 |
|
|
0356 FCF5 8E F6 30 LDX #COMBUF BUILD MESSAGE HERE
|
361 |
|
|
0357 *
|
362 |
|
|
0358 * First byte is a function code
|
363 |
|
|
0359 FCF8 BD FC 5F JSR GETCHAR GET A FUNCTION (6 bytes of stack)
|
364 |
|
|
0360 FCFB 25 F4 BCS MAIN JIF TIMEOUT: RESYNC
|
365 |
|
|
0361 FCFD 81 F7 CMPA #FN_MIN
|
366 |
|
|
0362 FCFF 25 F0 BLO MAIN JIF BELOW MIN: ILLEGAL FUNCTION
|
367 |
|
|
0363 FD01 A7 80 STA ,X+ SAVE FUNCTION CODE
|
368 |
|
|
0364 *
|
369 |
|
|
0365 * Second byte is data byte count (may be zero)
|
370 |
|
|
0366 FD03 BD FC 5F JSR GETCHAR GET A LENGTH BYTE
|
371 |
|
|
0367 FD06 25 E9 BCS MAIN JIF TIMEOUT: RESYNC
|
372 |
|
|
0368 FD08 81 80 CMPA #COMBUF_SIZE
|
373 |
|
|
0369 FD0A 22 E5 BHI MAIN JIF TOO LONG: ILLEGAL LENGTH
|
374 |
|
|
0370 FD0C A7 80 STA ,X+ SAVE LENGTH
|
375 |
|
|
0371 FD0E 81 00 CMPA #0
|
376 |
|
|
0372 FD10 27 0C BEQ MA80 SKIP DATA LOOP IF LENGTH = 0
|
377 |
|
|
0373 *
|
378 |
|
|
0374 * Loop for data
|
379 |
|
|
0375 FD12 1F 89 TFR A,B SAVE LENGTH FOR LOOP
|
380 |
|
|
0376 FD14 BD FC 5F MA10 JSR GETCHAR GET A DATA BYTE
|
381 |
|
|
0377 FD17 25 D8 BCS MAIN JIF TIMEOUT: RESYNC
|
382 |
|
|
0378 FD19 A7 80 STA ,X+ SAVE DATA BYTE
|
383 |
|
|
0379 FD1B 5A DECB
|
384 |
|
|
0380 FD1C 26 F6 BNE MA10
|
385 |
|
|
0381 *
|
386 |
|
|
0382 * Get the checksum
|
387 |
|
|
0383 FD1E BD FC 5F MA80 JSR GETCHAR GET THE CHECKSUM
|
388 |
|
|
0384 FD21 25 CE BCS MAIN JIF TIMEOUT: RESYNC
|
389 |
|
|
0385 FD23 34 02 PSHS A SAVE CHECKSUM
|
390 |
|
|
0386 *
|
391 |
|
|
0387 * Compare received checksum to that calculated on received buffer
|
392 |
|
|
0388 * (Sum should be 0)
|
393 |
|
|
0389 FD25 BD FE B4 JSR CHECKSUM
|
394 |
|
|
0390 FD28 AB E0 ADDA ,S+ ADD SAVED CHECKSUM TO COMPUTED
|
395 |
|
|
0391 FD2A 26 C5 BNE MAIN JIF BAD CHECKSUM
|
396 |
|
|
0392 *
|
397 |
|
|
0393 * Process the message.
|
398 |
|
|
0394 FD2C 8E F6 30 LDX #COMBUF
|
399 |
|
|
0395 FD2F A6 80 LDA ,X+ GET THE FUNCTION CODE
|
400 |
|
|
0396 FD31 E6 80 LDB ,X+ GET THE LENGTH
|
401 |
|
|
0397 FD33 81 FF CMPA #FN_GET_STAT
|
402 |
|
|
0398 FD35 27 42 BEQ TARGET_STAT
|
403 |
|
|
0399 FD37 81 FE CMPA #FN_READ_MEM
|
404 |
|
|
0400 FD39 27 26 BEQ JREAD_MEM
|
405 |
|
|
0401 FD3B 81 FD CMPA #FN_WRITE_M
|
406 |
|
|
0402 FD3D 27 25 BEQ JWRITE_MEM
|
407 |
|
|
0403 FD3F 81 FC CMPA #FN_READ_RG
|
408 |
|
|
0404 FD41 27 24 BEQ JREAD_REGS
|
409 |
|
|
0405 FD43 81 FB CMPA #FN_WRITE_RG
|
410 |
|
|
0406 FD45 27 23 BEQ JWRITE_REGS
|
411 |
|
|
0407 FD47 81 FA CMPA #FN_RUN_TARG
|
412 |
|
|
0408 FD49 27 22 BEQ JRUN_TARGET
|
413 |
|
|
0409 FD4B 81 F9 CMPA #FN_SET_BYTE
|
414 |
|
|
0410 FD4D 27 21 BEQ JSET_BYTES
|
415 |
|
|
0411 FD4F 81 F8 CMPA #FN_IN
|
416 |
|
|
0412 FD51 27 20 BEQ JIN_PORT
|
417 |
|
|
0413 FD53 81 F7 CMPA #FN_OUT
|
418 |
|
|
0414 FD55 27 1F BEQ JOUT_PORT
|
419 |
|
|
0415 *
|
420 |
|
|
0416 * Error: unknown function. Complain
|
421 |
|
|
0417 FD57 86 F0 LDA #FN_ERROR
|
422 |
|
|
0418 FD59 B7 F6 30 STA COMBUF SET FUNCTION AS "ERROR"
|
423 |
|
|
0419 FD5C 86 01 LDA #1
|
424 |
|
|
0420 FD5E 7E FE 92 JMP SEND_STATUS VALUE IS "ERROR"
|
425 |
|
|
0421 *
|
426 |
|
|
0422 * long jumps to handlers
|
427 |
|
|
0423 FD61 7E FD 8E JREAD_MEM JMP READ_MEM
|
428 |
|
|
0424 FD64 7E FD A5 JWRITE_MEM JMP WRITE_MEM
|
429 |
|
|
0425 FD67 7E FD D1 JREAD_REGS JMP READ_REGS
|
430 |
|
|
0426 FD6A 7E FD E6 JWRITE_REGS JMP WRITE_REGS
|
431 |
|
|
0427 FD6D 7E FD F8 JRUN_TARGET JMP RUN_TARGET
|
432 |
|
|
0428 FD70 7E FE 4B JSET_BYTES JMP SET_BYTES
|
433 |
|
|
0429 FD73 7E FE 79 JIN_PORT JMP IN_PORT
|
434 |
|
|
0430 FD76 7E FE 84 JOUT_PORT JMP OUT_PORT
|
435 |
|
|
0431
|
436 |
|
|
0432 *===========================================================================
|
437 |
|
|
0433 *
|
438 |
|
|
0434 * Target Status: FN, len
|
439 |
|
|
0435 *
|
440 |
|
|
0436 * Entry with A=function code, B=data size, X=COMBUF+2
|
441 |
|
|
0437 *
|
442 |
|
|
0438 TARGET_STAT
|
443 |
|
|
0439 FD79 8E FC 91 LDX #TSTG DATA FOR REPLY
|
444 |
|
|
0440 FD7C 10 8E F6 31 LDY #COMBUF+1 POINTER TO RETURN BUFFER
|
445 |
|
|
0441 FD80 C6 1B LDB #TSTG_SIZE LENGTH OF REPLY
|
446 |
|
|
0442 FD82 E7 A0 STB ,Y+ SET SIZE IN REPLY BUFFER
|
447 |
|
|
0443 FD84 A6 80 TS10 LDA ,X+ MOVE REPLY DATA TO BUFFER
|
448 |
|
|
0444 FD86 A7 A0 STA ,Y+
|
449 |
|
|
0445 FD88 5A DECB
|
450 |
|
|
0446 FD89 26 F9 BNE TS10
|
451 |
|
|
0447 *
|
452 |
|
|
0448 * Compute checksum on buffer, and send to master, then return
|
453 |
|
|
0449 FD8B 7E FE 9C JMP SEND
|
454 |
|
|
0450
|
455 |
|
|
0451 *===========================================================================
|
456 |
|
|
0452 *
|
457 |
|
|
0453 * Read Memory: FN, len, page, Alo, Ahi, Nbytes
|
458 |
|
|
0454 *
|
459 |
|
|
0455 * Entry with A=function code, B=data size, X=COMBUF+2
|
460 |
|
|
0456 *
|
461 |
|
|
0457 READ_MEM
|
462 |
|
|
0458 *
|
463 |
|
|
0459 * Set map
|
464 |
|
|
0460 *;;; LDA 0,X
|
465 |
|
|
0461 *;;; STA MAPIMG
|
466 |
|
|
0462 *;;; STA MAPREG
|
467 |
|
|
0463 *
|
468 |
|
|
0464 * Get address
|
469 |
|
|
0465 FD8E A6 02 LDA 2,X MSB OF ADDRESS IN A
|
470 |
|
|
0466 FD90 E6 01 LDB 1,X LSB OF ADDRESS IN B
|
471 |
|
|
0467 FD92 1F 02 TFR D,Y ADDRESS IN Y
|
472 |
|
|
0468 *
|
473 |
|
|
0469 * Prepare return buffer: FN (unchanged), LEN, DATA
|
474 |
|
|
0470 FD94 E6 03 LDB 3,X NUMBER OF BYTES TO RETURN
|
475 |
|
|
0471 FD96 F7 F6 31 STB COMBUF+1 RETURN LENGTH = REQUESTED DATA
|
476 |
|
|
0472 FD99 27 07 BEQ GLP90 JIF NO BYTES TO GET
|
477 |
|
|
0473 *
|
478 |
|
|
0474 * Read the requested bytes from local memory
|
479 |
|
|
0475 FD9B A6 A0 GLP LDA ,Y+ GET BYTE
|
480 |
|
|
0476 FD9D A7 80 STA ,X+ STORE TO RETURN BUFFER
|
481 |
|
|
0477 FD9F 5A DECB
|
482 |
|
|
0478 FDA0 26 F9 BNE GLP
|
483 |
|
|
0479 *
|
484 |
|
|
0480 * Compute checksum on buffer, and send to master, then return
|
485 |
|
|
0481 FDA2 7E FE 9C GLP90 JMP SEND
|
486 |
|
|
0482
|
487 |
|
|
0483 *===========================================================================
|
488 |
|
|
0484 *
|
489 |
|
|
0485 * Write Memory: FN, len, page, Alo, Ahi, (len-3 bytes of Data)
|
490 |
|
|
0486 *
|
491 |
|
|
0487 * Entry with A=function code, B=data size, X=COMBUF+2
|
492 |
|
|
0488 *
|
493 |
|
|
0489 * Uses 6 bytes of stack
|
494 |
|
|
0490 *
|
495 |
|
|
0491 WRITE_MEM
|
496 |
|
|
0492 *
|
497 |
|
|
0493 * Set map
|
498 |
|
|
0494 FDA5 A6 80 LDA ,X+
|
499 |
|
|
0495 *;;; STA MAPIMG
|
500 |
|
|
0496 *;;; STA MAPREG
|
501 |
|
|
0497 *
|
502 |
|
|
0498 * Get address
|
503 |
|
|
0499 FDA7 E6 80 LDB ,X+ LSB OF ADDRESS IN B
|
504 |
|
|
0500 FDA9 A6 80 LDA ,X+ MSB OF ADDRESS IN A
|
505 |
|
|
0501 FDAB 1F 02 TFR D,Y ADDRESS IN Y
|
506 |
|
|
0502 *
|
507 |
|
|
0503 * Compute number of bytes to write
|
508 |
|
|
0504 FDAD F6 F6 31 LDB COMBUF+1 NUMBER OF BYTES TO RETURN
|
509 |
|
|
0505 FDB0 C0 03 SUBB #3 MINUS PAGE AND ADDRESS
|
510 |
|
|
0506 FDB2 27 14 BEQ WLP50 JIF NO BYTES TO PUT
|
511 |
|
|
0507 *
|
512 |
|
|
0508 * Write the specified bytes to local memory
|
513 |
|
|
0509 FDB4 34 34 PSHS B,X,Y
|
514 |
|
|
0510 FDB6 A6 80 WLP LDA ,X+ GET BYTE TO WRITE
|
515 |
|
|
0511 FDB8 A7 A0 STA ,Y+ STORE THE BYTE AT ,Y
|
516 |
|
|
0512 FDBA 5A DECB
|
517 |
|
|
0513 FDBB 26 F9 BNE WLP
|
518 |
|
|
0514 *
|
519 |
|
|
0515 * Compare to see if the write worked
|
520 |
|
|
0516 FDBD 35 34 PULS B,X,Y
|
521 |
|
|
0517 FDBF A6 80 WLP20 LDA ,X+ GET BYTE JUST WRITTEN
|
522 |
|
|
0518 FDC1 A1 A0 CMPA ,Y+
|
523 |
|
|
0519 FDC3 26 07 BNE WLP80 BR IF WRITE FAILED
|
524 |
|
|
0520 FDC5 5A DECB
|
525 |
|
|
0521 FDC6 26 F7 BNE WLP20
|
526 |
|
|
0522 *
|
527 |
|
|
0523 * Write succeeded: return status = 0
|
528 |
|
|
0524 FDC8 86 00 WLP50 LDA #0 RETURN STATUS = 0
|
529 |
|
|
0525 FDCA 20 02 BRA WLP90
|
530 |
|
|
0526 *
|
531 |
|
|
0527 * Write failed: return status = 1
|
532 |
|
|
0528 FDCC 86 01 WLP80 LDA #1
|
533 |
|
|
0529
|
534 |
|
|
0530 * Return OK status
|
535 |
|
|
0531 FDCE 7E FE 92 WLP90 JMP SEND_STATUS
|
536 |
|
|
0532
|
537 |
|
|
0533 *===========================================================================
|
538 |
|
|
0534 *
|
539 |
|
|
0535 * Read registers: FN, len=0
|
540 |
|
|
0536 *
|
541 |
|
|
0537 * Entry with A=function code, B=data size, X=COMBUF+2
|
542 |
|
|
0538 *
|
543 |
|
|
0539 READ_REGS
|
544 |
|
|
0540 *
|
545 |
|
|
0541 * Enter here from SWI after "RUN" and "STEP" to return task registers
|
546 |
|
|
0542 RETURN_REGS
|
547 |
|
|
0543 FDD1 10 8E F6 20 LDY #TASK_REGS POINTER TO REGISTERS
|
548 |
|
|
0544 FDD5 C6 10 LDB #TASK_REG_SZ NUMBER OF BYTES
|
549 |
|
|
0545 FDD7 8E F6 31 LDX #COMBUF+1 POINTER TO RETURN BUFFER
|
550 |
|
|
0546 FDDA E7 80 STB ,X+ SAVE RETURN DATA LENGTH
|
551 |
|
|
0547 *
|
552 |
|
|
0548 * Copy the registers
|
553 |
|
|
0549 FDDC A6 A0 GRLP LDA ,Y+ GET BYTE TO A
|
554 |
|
|
0550 FDDE A7 80 STA ,X+ STORE TO RETURN BUFFER
|
555 |
|
|
0551 FDE0 5A DECB
|
556 |
|
|
0552 FDE1 26 F9 BNE GRLP
|
557 |
|
|
0553 *
|
558 |
|
|
0554 * Compute checksum on buffer, and send to master, then return
|
559 |
|
|
0555 FDE3 7E FE 9C JMP SEND
|
560 |
|
|
0556
|
561 |
|
|
0557 *===========================================================================
|
562 |
|
|
0558 *
|
563 |
|
|
0559 * Write registers: FN, len, (register image)
|
564 |
|
|
0560 *
|
565 |
|
|
0561 * Entry with A=function code, B=data size, X=COMBUF+2
|
566 |
|
|
0562 *
|
567 |
|
|
0563 WRITE_REGS
|
568 |
|
|
0564 *
|
569 |
|
|
0565 FDE6 5D TSTB NUMBER OF BYTES
|
570 |
|
|
0566 FDE7 27 0B BEQ WRR80 JIF NO REGISTERS
|
571 |
|
|
0567 *
|
572 |
|
|
0568 * Copy the registers
|
573 |
|
|
0569 FDE9 10 8E F6 20 LDY #TASK_REGS POINTER TO REGISTERS
|
574 |
|
|
0570 FDED A6 80 WRRLP LDA ,X+ GET BYTE TO A
|
575 |
|
|
0571 FDEF A7 A0 STA ,Y+ STORE TO REGISTER RAM
|
576 |
|
|
0572 FDF1 5A DECB
|
577 |
|
|
0573 FDF2 26 F9 BNE WRRLP
|
578 |
|
|
0574 *
|
579 |
|
|
0575 * Return OK status
|
580 |
|
|
0576 FDF4 4F WRR80 CLRA
|
581 |
|
|
0577 FDF5 7E FE 92 JMP SEND_STATUS
|
582 |
|
|
0578
|
583 |
|
|
0579 *===========================================================================
|
584 |
|
|
0580 *
|
585 |
|
|
0581 * Run Target: FN, len
|
586 |
|
|
0582 *
|
587 |
|
|
0583 * Entry with A=function code, B=data size, X=COMBUF+2
|
588 |
|
|
0584 *
|
589 |
|
|
0585 RUN_TARGET
|
590 |
|
|
0586 *
|
591 |
|
|
0587 * Restore user's map
|
592 |
|
|
0588 ** LDA REG_PAGE USER'S PAGE
|
593 |
|
|
0589 ** STA MAPIMG SET IMAGE
|
594 |
|
|
0590 ** STA MAPREG SET MAPPING REGISTER
|
595 |
|
|
0591 *
|
596 |
|
|
0592 * Switch to user stack
|
597 |
|
|
0593 FDF8 B6 F6 23 LDA REG_SP+1 BACK TO USER STACK
|
598 |
|
|
0594 FDFB F6 F6 22 LDB REG_SP
|
599 |
|
|
0595 FDFE 1F 04 TFR D,S TO S
|
600 |
|
|
0596 *
|
601 |
|
|
0597 * Restore registers
|
602 |
|
|
0598 FE00 B6 F6 2F LDA REG_PC+1 MS USER PC FOR RTI
|
603 |
|
|
0599 FE03 F6 F6 2E LDB REG_PC LS USER PC FOR RTI
|
604 |
|
|
0600 FE06 34 06 PSHS D
|
605 |
|
|
0601 *
|
606 |
|
|
0602 FE08 B6 F6 25 LDA REG_U+1
|
607 |
|
|
0603 FE0B F6 F6 24 LDB REG_U
|
608 |
|
|
0604 FE0E 34 06 PSHS D
|
609 |
|
|
0605 *
|
610 |
|
|
0606 FE10 B6 F6 27 LDA REG_Y+1
|
611 |
|
|
0607 FE13 F6 F6 26 LDB REG_Y
|
612 |
|
|
0608 FE16 34 06 PSHS D
|
613 |
|
|
0609 *
|
614 |
|
|
0610 FE18 B6 F6 29 LDA REG_X+1
|
615 |
|
|
0611 FE1B F6 F6 28 LDB REG_X
|
616 |
|
|
0612 FE1E 34 06 PSHS D
|
617 |
|
|
0613 *
|
618 |
|
|
0614 FE20 B6 F6 2C LDA REG_DP
|
619 |
|
|
0615 FE23 34 02 PSHS A
|
620 |
|
|
0616 *
|
621 |
|
|
0617 FE25 B6 F6 2A LDA REG_B
|
622 |
|
|
0618 FE28 34 02 PSHS A
|
623 |
|
|
0619 *
|
624 |
|
|
0620 FE2A B6 F6 2B LDA REG_A
|
625 |
|
|
0621 FE2D 34 02 PSHS A
|
626 |
|
|
0622 *
|
627 |
|
|
0623 FE2F B6 F6 2D LDA REG_CC SAVE USER CONDITION CODES FOR RTI
|
628 |
|
|
0624 FE32 8A 50 ORA #E _MUST_ BE "ALL REGS PUSHED"
|
629 |
|
|
0625 FE34 34 02 PSHS A
|
630 |
|
|
0626 *
|
631 |
|
|
0627 * Return to user
|
632 |
|
|
0628 FE36 3B RTI
|
633 |
|
|
0629 *
|
634 |
|
|
0630 *===========================================================================
|
635 |
|
|
0631 *
|
636 |
|
|
0632 * Common continue point for all monitor entrances
|
637 |
|
|
0633 * SP = user stack
|
638 |
|
|
0634 ENTER_MON
|
639 |
|
|
0635 FE37 1F 40 TFR S,D USER STACK POINTER
|
640 |
|
|
0636 FE39 B7 F6 23 STA REG_SP+1 SAVE USER'S STACK POINTER (MSB)
|
641 |
|
|
0637 FE3C F7 F6 22 STB REG_SP LSB
|
642 |
|
|
0638 *
|
643 |
|
|
0639 * Change to our own stack
|
644 |
|
|
0640 FE3F 10 CE F6 20 LDS #MONSTACK AND USE OURS INSTEAD
|
645 |
|
|
0641 *
|
646 |
|
|
0642 * Operating system variables
|
647 |
|
|
0643 ** LDA MAPIMG GET CURRENT USER MAP
|
648 |
|
|
0644 FE43 86 00 LDA #0 ... OR ZERO IF UNMAPPED TARGET
|
649 |
|
|
0645 FE45 B7 F6 21 STA REG_PAGE SAVE USER'S PAGE
|
650 |
|
|
0646 *
|
651 |
|
|
0647 * Return registers to master
|
652 |
|
|
0648 FE48 7E FD D1 JMP RETURN_REGS
|
653 |
|
|
0649
|
654 |
|
|
0650 *===========================================================================
|
655 |
|
|
0651 *
|
656 |
|
|
0652 * Set target byte(s): FN, len { (page, alow, ahigh, data), (...)... }
|
657 |
|
|
0653 *
|
658 |
|
|
0654 * Entry with A=function code, B=data size, X=COMBUF+2
|
659 |
|
|
0655 *
|
660 |
|
|
0656 * Return has FN, len, (data from memory locations)
|
661 |
|
|
0657 *
|
662 |
|
|
0658 * If error in insert (memory not writable), abort to return short data
|
663 |
|
|
0659 *
|
664 |
|
|
0660 * This function is used primarily to set and clear breakpoints
|
665 |
|
|
0661 *
|
666 |
|
|
0662 * Uses 1 byte of stack
|
667 |
|
|
0663 *
|
668 |
|
|
0664 SET_BYTES
|
669 |
|
|
0665 FE4B CE F6 31 LDU #COMBUF+1 POINTER TO RETURN BUFFER
|
670 |
|
|
0666 FE4E 86 00 LDA #0
|
671 |
|
|
0667 FE50 A7 C0 STA ,U+ SET RETURN COUNT AS ZERO
|
672 |
|
|
0668 FE52 54 LSRB
|
673 |
|
|
0669 FE53 54 LSRB LEN/4 = NUMBER OF BYTES TO SET
|
674 |
|
|
0670 FE54 27 20 BEQ SB99 JIF NO BYTES (COMBUF+1 = 0)
|
675 |
|
|
0671 *
|
676 |
|
|
0672 * Loop on inserting bytes
|
677 |
|
|
0673 FE56 34 04 SB10 PSHS B SAVE LOOP COUNTER
|
678 |
|
|
0674 *
|
679 |
|
|
0675 * Set map
|
680 |
|
|
0676 *;;; LDA 0,X
|
681 |
|
|
0677 *;;; STA MAPIMG
|
682 |
|
|
0678 *;;; STA MAPREG
|
683 |
|
|
0679 *
|
684 |
|
|
0680 * Get address
|
685 |
|
|
0681 FE58 A6 02 LDA 2,X MSB OF ADDRESS IN A
|
686 |
|
|
0682 FE5A E6 01 LDB 1,X LSB OF ADDRESS IN B
|
687 |
|
|
0683 FE5C 1F 02 TFR D,Y MEMORY ADDRESS IN Y
|
688 |
|
|
0684 *
|
689 |
|
|
0685 * Read current data at byte location
|
690 |
|
|
0686 FE5E A6 A4 LDA 0,Y
|
691 |
|
|
0687 *
|
692 |
|
|
0688 * Insert new data at byte location
|
693 |
|
|
0689 FE60 E6 03 LDB 3,X GET BYTE TO STORE
|
694 |
|
|
0690 FE62 E7 A4 STB 0,Y WRITE TARGET MEMORY
|
695 |
|
|
0691 *
|
696 |
|
|
0692 * Verify write
|
697 |
|
|
0693 FE64 E1 A4 CMPB 0,Y READ TARGET MEMORY
|
698 |
|
|
0694 FE66 35 04 PULS B RESTORE LOOP COUNT, CC'S INTACT
|
699 |
|
|
0695 FE68 26 0C BNE SB90 BR IF INSERT FAILED: ABORT
|
700 |
|
|
0696 *
|
701 |
|
|
0697 * Save target byte in return buffer
|
702 |
|
|
0698 FE6A A7 C0 STA ,U+
|
703 |
|
|
0699 FE6C 7C F6 31 INC COMBUF+1 COUNT ONE RETURN BYTE
|
704 |
|
|
0700 *
|
705 |
|
|
0701 * Loop for next byte
|
706 |
|
|
0702 FE6F 30 04 LEAX 4,X STEP TO NEXT BYTE SPECIFIER
|
707 |
|
|
0703 FE71 F1 F6 31 CMPB COMBUF+1
|
708 |
|
|
0704 FE74 26 E0 BNE SB10 *LOOP FOR ALL BYTES
|
709 |
|
|
0705 *
|
710 |
|
|
0706 * Return buffer with data from byte locations
|
711 |
|
|
0707 SB90
|
712 |
|
|
0708 *
|
713 |
|
|
0709 * Compute checksum on buffer, and send to master, then return
|
714 |
|
|
0710 FE76 7E FE 9C SB99 JMP SEND
|
715 |
|
|
0711
|
716 |
|
|
0712 *===========================================================================
|
717 |
|
|
0713 *
|
718 |
|
|
0714 * Input from port: FN, len, PortAddressLo, PAhi (=0)
|
719 |
|
|
0715 *
|
720 |
|
|
0716 * While the 6809 has no input or output instructions, we retain these
|
721 |
|
|
0717 * to allow write-without-verify
|
722 |
|
|
0718 *
|
723 |
|
|
0719 * Entry with A=function code, B=data size, X=COMBUF+2
|
724 |
|
|
0720 *
|
725 |
|
|
0721 IN_PORT
|
726 |
|
|
0722 *
|
727 |
|
|
0723 * Get port address
|
728 |
|
|
0724 FE79 A6 01 LDA 1,X MSB OF ADDRESS IN A
|
729 |
|
|
0725 FE7B E6 84 LDB 0,X LSB OF ADDRESS IN B
|
730 |
|
|
0726 FE7D 1F 02 TFR D,Y MEMORY ADDRESS IN Y
|
731 |
|
|
0727 *
|
732 |
|
|
0728 * Read the requested byte from local memory
|
733 |
|
|
0729 FE7F A6 A4 LDA 0,Y
|
734 |
|
|
0730 *
|
735 |
|
|
0731 * Return byte read as "status"
|
736 |
|
|
0732 FE81 7E FE 92 JMP SEND_STATUS
|
737 |
|
|
0733
|
738 |
|
|
0734 *===========================================================================
|
739 |
|
|
0735 *
|
740 |
|
|
0736 * Output to port FN, len, PortAddressLo, PAhi (=0), data
|
741 |
|
|
0737 *
|
742 |
|
|
0738 * Entry with A=function code, B=data size, X=COMBUF+2
|
743 |
|
|
0739 *
|
744 |
|
|
0740 OUT_PORT
|
745 |
|
|
0741 *
|
746 |
|
|
0742 * Get port address
|
747 |
|
|
0743 FE84 A6 01 LDA 1,X MSB OF ADDRESS IN A
|
748 |
|
|
0744 FE86 E6 84 LDB 0,X LSB OF ADDRESS IN B
|
749 |
|
|
0745 FE88 1F 02 TFR D,Y MEMORY ADDRESS IN Y
|
750 |
|
|
0746 *
|
751 |
|
|
0747 * Get data
|
752 |
|
|
0748 FE8A A6 02 LDA 2,X
|
753 |
|
|
0749 *
|
754 |
|
|
0750 * Write value to port
|
755 |
|
|
0751 FE8C A7 A4 STA 0,Y
|
756 |
|
|
0752 *
|
757 |
|
|
0753 * Do not read port to verify (some I/O devices don't like it)
|
758 |
|
|
0754 *
|
759 |
|
|
0755 * Return status of OK
|
760 |
|
|
0756 FE8E 4F CLRA
|
761 |
|
|
0757 FE8F 7E FE 92 JMP SEND_STATUS
|
762 |
|
|
0758
|
763 |
|
|
0759 *===========================================================================
|
764 |
|
|
0760 * Build status return with value from "A"
|
765 |
|
|
0761 *
|
766 |
|
|
0762 SEND_STATUS
|
767 |
|
|
0763 FE92 B7 F6 32 STA COMBUF+2 SET STATUS
|
768 |
|
|
0764 FE95 86 01 LDA #1
|
769 |
|
|
0765 FE97 B7 F6 31 STA COMBUF+1 SET LENGTH
|
770 |
|
|
0766 FE9A 20 00 BRA SEND
|
771 |
|
|
0767
|
772 |
|
|
0768 *===========================================================================
|
773 |
|
|
0769 * Append checksum to COMBUF and send to master
|
774 |
|
|
0770 *
|
775 |
|
|
0771 FE9C BD FE B4 SEND JSR CHECKSUM GET A=CHECKSUM, X->checksum location
|
776 |
|
|
0772 FE9F 40 NEGA
|
777 |
|
|
0773 FEA0 A7 84 STA 0,X STORE NEGATIVE OF CHECKSUM
|
778 |
|
|
0774 *
|
779 |
|
|
0775 * Send buffer to master
|
780 |
|
|
0776 FEA2 8E F6 30 LDX #COMBUF POINTER TO DATA
|
781 |
|
|
0777 FEA5 E6 01 LDB 1,X LENGTH OF DATA
|
782 |
|
|
0778 FEA7 CB 03 ADDB #3 PLUS FUNCTION, LENGTH, CHECKSUM
|
783 |
|
|
0779 FEA9 A6 80 SND10 LDA ,X+
|
784 |
|
|
0780 FEAB BD FC 7C JSR PUTCHAR SEND A BYTE
|
785 |
|
|
0781 FEAE 5A DECB
|
786 |
|
|
0782 FEAF 26 F8 BNE SND10
|
787 |
|
|
0783 FEB1 7E FC F1 JMP MAIN BACK TO MAIN LOOP
|
788 |
|
|
0784
|
789 |
|
|
0785 *===========================================================================
|
790 |
|
|
0786 * Compute checksum on COMBUF. COMBUF+1 has length of data,
|
791 |
|
|
0787 * Also include function byte and length byte
|
792 |
|
|
0788 *
|
793 |
|
|
0789 * Returns:
|
794 |
|
|
0790 * A = checksum
|
795 |
|
|
0791 * X = pointer to next byte in buffer (checksum location)
|
796 |
|
|
0792 * B is scratched
|
797 |
|
|
0793 *
|
798 |
|
|
0794 CHECKSUM
|
799 |
|
|
0795 FEB4 8E F6 30 LDX #COMBUF pointer to buffer
|
800 |
|
|
0796 FEB7 E6 01 LDB 1,X length of message
|
801 |
|
|
0797 FEB9 CB 02 ADDB #2 plus function, length
|
802 |
|
|
0798 FEBB 86 00 LDA #0 init checksum to 0
|
803 |
|
|
0799 FEBD AB 80 CHK10 ADDA ,X+
|
804 |
|
|
0800 FEBF 5A DECB
|
805 |
|
|
0801 FEC0 26 FB BNE CHK10 loop for all
|
806 |
|
|
0802 FEC2 39 RTS return with checksum in A
|
807 |
|
|
0803
|
808 |
|
|
0804 ***********************************************************************
|
809 |
|
|
0805 *
|
810 |
|
|
0806 * Interrupt handlers to catch unused interrupts and traps
|
811 |
|
|
0807 * Registers are stacked. Jump through RAM vector using X, type in A
|
812 |
|
|
0808 *
|
813 |
|
|
0809 * This will affect only interrupt routines looking for register values!
|
814 |
|
|
0810 *
|
815 |
|
|
0811 * Our default handler uses the code in "A" as the processor state to be
|
816 |
|
|
0812 * passed back to the host.
|
817 |
|
|
0813 *
|
818 |
|
|
0814 FEC3 86 07 RES_ENT LDA #7
|
819 |
|
|
0815 FEC5 BE F0 00 LDX RAMVEC+0
|
820 |
|
|
0816 FEC8 6E 84 JMP 0,X
|
821 |
|
|
0817 *
|
822 |
|
|
0818 FECA 86 06 SWI3_ENT LDA #6
|
823 |
|
|
0819 FECC BE F0 02 LDX RAMVEC+2
|
824 |
|
|
0820 FECF 6E 84 JMP 0,X
|
825 |
|
|
0821 *
|
826 |
|
|
0822 FED1 86 05 SWI2_ENT LDA #5
|
827 |
|
|
0823 FED3 BE F0 04 LDX RAMVEC+4
|
828 |
|
|
0824 FED6 6E 84 JMP 0,X
|
829 |
|
|
0825 *
|
830 |
|
|
0826 * May have only PC and CC's pushed (unless we were waiting for an interrupt)
|
831 |
|
|
0827 * Push all registers here for common entry (else we can't use our RAM vector)
|
832 |
|
|
0828 FED8 B7 F6 2B FIRQ_ENT STA REG_A SAVE A REG
|
833 |
|
|
0829 FEDB 35 02 PULS A GET CC'S FROM STACK
|
834 |
|
|
0830 FEDD 85 50 BITA #E
|
835 |
|
|
0831 FEDF 26 09 BNE FIRQ9 BR IF ALL REGISTERS PUSHED ALREADY
|
836 |
|
|
0832 FEE1 34 7C PSHS U,Y,X,DP,B ELSE PUSH THEM NOW
|
837 |
|
|
0833 FEE3 F6 F6 2B LDB REG_A
|
838 |
|
|
0834 FEE6 34 04 PSHS B
|
839 |
|
|
0835 FEE8 8A 50 ORA #E SET AS "ALL REGS PUSHED"
|
840 |
|
|
0836 FEEA 34 02 FIRQ9 PSHS A REPLACE CC'S
|
841 |
|
|
0837 FEEC 86 04 LDA #4
|
842 |
|
|
0838 FEEE BE F0 06 LDX RAMVEC+6
|
843 |
|
|
0839 FEF1 6E 84 JMP 0,X
|
844 |
|
|
0840 *
|
845 |
|
|
0841 FEF3 86 03 IRQ_ENT LDA #3
|
846 |
|
|
0842 FEF5 BE F0 08 LDX RAMVEC+8
|
847 |
|
|
0843 FEF8 6E 84 JMP 0,X
|
848 |
|
|
0844 *
|
849 |
|
|
0845 FEFA 86 02 NMI_ENT LDA #2
|
850 |
|
|
0846 FEFC BE F0 0C LDX RAMVEC+12
|
851 |
|
|
0847 FEFF 6E 84 JMP 0,X
|
852 |
|
|
0848 *
|
853 |
|
|
0849 FF01 86 01 SWI_ENT LDA #1
|
854 |
|
|
0850 FF03 7E FC AC JMP INT_ENTRY
|
855 |
|
|
0851 *
|
856 |
|
|
0852 *============================================================================
|
857 |
|
|
0853 * VECTORS THROUGH RAM
|
858 |
|
|
0854 FFF0 ORG HARD_VECT
|
859 |
|
|
0855
|
860 |
|
|
0856 FFF0 FE C3 FDB RES_ENT fff0 (reserved)
|
861 |
|
|
0857 FFF2 FE CA FDB SWI3_ENT fff2 (SWI3)
|
862 |
|
|
0858 FFF4 FE D1 FDB SWI2_ENT fff4 (SWI2)
|
863 |
|
|
0859 FFF6 FE D8 FDB FIRQ_ENT fff6 (FIRQ)
|
864 |
|
|
0860 FFF8 FE F3 FDB IRQ_ENT fff8 (IRQ)
|
865 |
|
|
0861 FFFA FF 01 FDB SWI_ENT fffa (SWI/breakpoint)
|
866 |
|
|
0862 FFFC FE FA FDB NMI_ENT fffc (NMI)
|
867 |
|
|
0863 FFFE FC 00 FDB RESET fffe reset
|
868 |
|
|
0864 *
|
869 |
|
|
0865 END RESET
|
870 |
|
|
Program + Init Data = 790 bytes
|
871 |
|
|
Error count = 0
|