0100 ;D1:CHAA.M65 0110 ;(c)1987 Antic Publishing 0120 ;Written by Patrick Bass 0130 ;Included from D:CHARLIE.M65 0140 ; 0150 ;Load address into pointer. 0160 ;Example: LEA.W LABEL,POINTER 0170 ; 0180 .MACRO LEA.W 0190 LDA # <%1 0200 LDY # >%1 0210 STA %2 0220 STY %2+1 0230 .ENDM 0240 ; 0250 ;Move a single byte in memory. 0260 ;Example: MOVE.B SOURCE,DEST 0270 ; 0280 .MACRO MOVE.B 0290 LDA %1 0300 STA %2 0310 .ENDM 0320 ; 0330 ;Move a single word in memory. 0340 ;Example: MOVE.W SOURCE,DEST 0350 ; 0360 .MACRO MOVE.W 0370 MOVE.B %1,%2 0380 MOVE.B %1+1,%2+1 0390 .ENDM 0400 ; 0410 ;Add a WORD value to a pointer 0420 ;Example: ADD.W 5,AMOUNT 0430 ; 0440 .MACRO ADD.W 0450 CLC 0460 LDA # <%1 0470 ADC %2 0480 STA %2 0490 LDA # >%1 0500 ADC %2+1 0510 STA %2+1 0520 .ENDM 0530 ; 0540 ;Fix Proper master pointers. 0550 ;Ex: FIX BASE,OFFSET,POINTER 0560 ; 0570 .MACRO FIX 0580 LDY #4 0590 CLC 0600 LDA (%1),Y 0610 ADC # <%2 0620 STA %3 0630 INY 0640 LDA (%1),Y 0650 ADC # >%2 0660 STA %3+1 0670 .ENDM 0680 ; 0690 ;------------------------------- 0700 ; Constants 0710 ; 0720 CTRL.SHIFT.ESCAPE = $80+$40+$1C 0730 POINTER.A = $DA ;Over here! 0740 POINTER.B = $DC ;Over there! 0750 P.A = POINTER.A 0760 P.B = POINTER.B 0770 ; 0780 STARTCODE = $2400 ;Gonzo 0790 SDLSTL = $0230 ;Dlist shadow 0800 VKEYBD = $0208 ;Vec: Keyboard 0810 MEMLO = $02E7 ;Down in Dixie 0820 WARMST = $08 ;Sugar Bear 0830 BASIC.WARM.START = $A000 0840 KBCODE = $D209 ;Whatz pressed? 0850 OPTION.BYTE = $FFF1 ;Whos there? 0860 XL.XE.SERIES = 2 ;Type of type 0870 STOPLN = $BA ;Where stopped. 0880 ERRSAVE = 195 ;Last err known 0890 LBUFF = $0580 ;BASIC buildnum 0900 INBUFF = $F3 ;Here too 0910 CIX = $F2 ;Character index 0920 FR0 = $D4 ;Float zero 0930 IFP = $D9AA ;Integer->Float 0940 FASC = $D8E6 ;Float->ATASCII 0950 ; 0960 WINDOW.FLAG = $0400 ;Window on? 0970 ; 0980 ; Offsets for printable lines. 0990 WINDOW.OFFSET = [40*2]+4 1000 REPORT.OFFSET = [40*5]+6 1010 ERROR.OFFSET = [40*7]+14 1020 LINE.OFFSET = [40*8]+14 1030 ;...and contractions. 1040 W.O = WINDOW.OFFSET 1050 R.O = REPORT.OFFSET 1060 E.O = ERROR.OFFSET 1070 L.O = LINE.OFFSET 1080 ; 1090 ;--------------------------- 1100 ;So the program code starts 1110 ; right here, and jumps. 1120 *= STARTCODE 1130 JMP SETUP 1140 ; 1150 ;- - - - - - - - - - - - - - 1160 ACCESSORY 1170 ;Save current acc. 1180 ;Was key press CTRL-ALT-ESC? 1190 ;Branch over if it was... 1200 PHA 1210 LDA KBCODE 1220 CMP #CTRL.SHIFT.ESCAPE 1230 BEQ SETSTART 1240 ; 1250 ;Else not right char, is 1260 ; window currently up? 1270 ;Branch out if not... else erase 1280 LDA WINDOW.FLAG 1290 BEQ SETX 1300 ; 1310 SETSTART 1320 ;Toggle window-on flag. 1330 LDA WINDOW.FLAG 1340 EOR #1 1350 STA WINDOW.FLAG 1360 ; 1370 ;Stack rest of registers. 1380 TYA 1390 PHA 1400 TXA 1410 PHA 1420 ; 1430 ;Is window coming up? 1440 ;Branch if not... 1450 LDA WINDOW.FLAG 1460 BEQ SETOFF 1470 ; 1480 ;Else open, work the window. 1490 JSR OPEN.WINDOW 1500 JSR WORK.WINDOW 1510 JMP SETX1 1520 SETOFF 1530 JSR CLOSE.WINDOW 1540 SETX1 1550 PLA 1560 TAX 1570 PLA 1580 TAY 1590 SETX 1600 ;Folks, I know all about 1610 ;indirect jumps. MAC65 would 1620 ; not let me grab the old 1630 ;VKEYBD vector. Don't know why. 1640 ; 1650 LDA OPTION.BYTE 1660 CMP #XL.XE.SERIES 1670 BNE MAYBE.THE.1200XL 1680 ; 1690 PLA 1700 JMP $FC19 1710 ; 1720 MAYBE.THE.1200XL 1730 CMP #1 1740 BNE ITS.AN.800 1750 ; 1760 PLA 1770 JMP $FC0C 1780 ; 1790 ITS.AN.800 1800 PLA 1810 JMP $FFBE 1820 ; 1830 ;----------------- 1840 W.SCREEN 1850 .WORD 0 ;Window 1860 R.SCREEN 1870 .WORD 0 ;Report Line 1880 E.SCREEN 1890 .WORD 0 ;Error Line 1900 L.SCREEN 1910 .WORD 0 ;Line Line 1920 C.MESS 1930 .BYTE " CHARLIE!" 1940 .BYTE " is active.",0 1950 C.SCREEN 1960 .WORD 0 ;CHAS Line 1970 ; 1980 ;- - - - - - - - - - - - - 1990 SETUP 2000 ;Don't listen to anybody. 2010 ;Make sure window is down... 2020 ;...and we print normal text. 2030 ; Point MEMLO at $3000. 2040 ;Build new pointers into window 2050 ;Tell 'em CHARLIEs active. 2060 ;Replace Keyboard Vector 2070 ;Start listening again... 2080 ;...and initialize BASIC. 2090 ; 2100 SEI 2110 LDA #0 2120 STA WINDOW.FLAG 2130 STA REVERSE.FLAG 2140 LEA.W $3000,MEMLO 2150 ; 2160 MOVE.W SDLSTL,POINTER.A 2170 FIX P.A,W.O,W.SCREEN 2180 FIX P.A,R.O,R.SCREEN 2190 FIX P.A,E.O,E.SCREEN 2200 FIX P.A,L.O,L.SCREEN 2210 FIX P.A,5,C.SCREEN 2220 ; 2230 LEA.W C.MESS,POINTER.A 2240 MOVE.W C.SCREEN,POINTER.B 2250 JSR WIND.LINE.OUT 2260 ; 2270 LEA.W ACCESSORY,VKEYBD 2280 LDA #0 2290 STA WARMST 2300 CLI 2310 JMP BASIC.WARM.START 2320 ; 2330 ;- - - - - - - - - - - - - 2340 .WORD 0,0,0 2350 WINDOW 2360 .BYTE "��������������������" 2370 WIND.W = *-WINDOW 2380 .BYTE "�����������š������" 2390 .BYTE "��������������������" 2400 .BYTE "��������������������" 2410 .BYTE "��������������������" 2420 .BYTE "�������������� �" 2430 .BYTE "������庠�������� �" 2440 .BYTE "��������������������" 2450 .BYTE "��� �����" 2460 .BYTE "��������������������" 2470 WIND.H = [*-WINDOW-1]/WIND.W 2480 .WORD 0 2490 W.BUFF 2500 *= *+[*-WINDOW] 2510 .WORD 0 2520 ; 2530 ;-------------------------- 2540 OPEN.WINDOW 2550 JSR INIT.OPEN ;Set pointers 2560 ; 2570 LDX #WIND.H 2580 OW1 2590 LDY #0 2600 O1FROM 2610 LDA $1234,Y ;Copy the screen 2620 STA $1234,Y ;to buffer. 2630 ; 2640 LDA $1234,Y ;Copy the window 2650 JSR ADJUST ;in screen code 2660 STA $1234,Y ;to the screen. 2670 ; 2680 INY 2690 CPY #WIND.W 2700 BCC O1FROM 2710 ; 2720 ADD.W 40,O1FROM+1 2730 ADD.W WIND.W,O1FROM+4 2740 ADD.W WIND.W,O1FROM+7 2750 ADD.W 40,O1FROM+13 2760 DEX 2770 BPL OW1 2780 ; 2790 RTS 2800 ; 2810 ;- - - - - - - - - - - - - - 2820 INIT.OPEN 2830 MOVE.W W.SCREEN,O1FROM+1 2840 LEA.W W.BUFF,O1FROM+4 2850 ; 2860 LEA.W WINDOW,O1FROM+7 2870 MOVE.W W.SCREEN,O1FROM+13 2880 ; 2890 RTS 2900 ; 2910 ;---------------------------- 2920 CLOSE.WINDOW 2930 JSR INIT.CLOSE 2940 ; 2950 LDX #WIND.H 2960 CW1 2970 LDY #0 2980 CFROM 2990 LDA $1234,Y :Copy buffer 3000 STA $1234,Y ;back to screen 3010 ; 3020 INY 3030 CPY #WIND.W 3040 BCC CFROM 3050 ; 3060 ADD.W WIND.W,CFROM+1 3070 ADD.W 40,CFROM+4 3080 DEX 3090 BPL CW1 3100 ; 3110 RTS 3120 ; 3130 ;- - - - - - - - - - - - - - 3140 INIT.CLOSE 3150 LEA.W W.BUFF,CFROM+1 3160 MOVE.W W.SCREEN,CFROM+4 3170 RTS 3180 ; 3190 ;---------------------------- 3200 ADJUST 3210 PHA 3220 AND #$80 3230 STA ADJUST.BIT 3240 PLA 3250 AND #$7F 3260 ; 3270 CMP #32 ;less than 32? 3280 BCS AJ1 ;Branch if not. 3290 ; 3300 ADC #64 ;Else add 64 3310 BCC AJX ;and split. 3320 AJ1 3330 CMP #96 ;Is char >=96? 3340 BCS AJX ;branch if yes 3350 ; 3360 SEC ;Else 31>chr<96 3370 SBC #32 3380 AJX 3390 ORA ADJUST.BIT 3400 RTS 3410 ; 3420 ADJUST.BIT 3430 .BYTE 0 3440 ; 3450 ;------------------------ 3460 FIX.LBUFF 3470 LDY #$FF 3480 FX1 3490 INY 3500 LDA (INBUFF),Y 3510 BPL FX1 3520 ; 3530 AND #$7F 3540 STA (INBUFF),Y 3550 INY 3560 LDA #0 3570 STA (INBUFF),Y 3580 RTS 3590 ; 3600 ;------------------------ 3610 WORK.WINDOW 3620 ;Set to print in reverse... 3630 ;...and make FR0/CIX zero. 3640 LDA #$80 3650 STA REVERSE.FLAG 3660 LEA.W 0,FR0 3670 MOVE.B FR0,CIX 3680 ; 3690 ;We print the value in ERRSAVE 3700 MOVE.B ERRSAVE,FR0 3710 ; 3720 ;Integer to float... 3730 ;...Float to ATASCII. 3740 ;Place zero on end, print it. 3750 JSR IFP 3760 JSR FASC 3770 JSR FIX.LBUFF 3780 LEA.W LBUFF,POINTER.A 3790 MOVE.W E.SCREEN,POINTER.B 3800 JSR WIND.LINE.OUT 3810 ; 3820 ;Ditto with the value in STOPLN 3830 MOVE.W STOPLN,FR0 3840 LDA #0 3850 STA CIX 3860 JSR IFP 3870 JSR FASC 3880 JSR FIX.LBUFF 3890 LEA.W LBUFF,POINTER.A 3900 MOVE.W L.SCREEN,POINTER.B 3910 JSR WIND.LINE.OUT 3920 ; 3930 ;- - - - - - - - - - - - - - - 3940 ;Now, to pick up proper error 3950 ;text string, first get error 3960 ;number, and compare it against 3970 ;each entry in a table of known 3980 ;error codes. 3990 ; 4000 LDA ERRSAVE 4010 LDX #NUM.ERR.ENTRIES-1 4020 WW1 4030 CMP ERROR.TABLE,X ;match? 4040 BEQ WW2 ;branch on match 4050 ; 4060 DEX ;else next 4070 BPL WW1 ;until finis. 4080 LDX #43 ;NO MATCH 4090 WW2 4100 ;At this point, a match was 4110 ;found in the table, and the 4120 ;X register contains the number 4130 ;of the error entry. 4140 TXA 4150 ASL A ;pointerize it. 4160 TAX 4170 ; 4180 ;Now pick up the address of the 4190 ;coresponding error string and 4200 ;place inside POINTER.A 4210 ;Then print the string out. 4220 LDA ERROR.JUMP,X 4230 STA POINTER.A 4240 LDA ERROR.JUMP+1,X 4250 STA POINTER.A+1 4260 MOVE.W R.SCREEN,POINTER.B 4270 JSR WIND.LINE.OUT 4280 WWX 4290 RTS 4300 ; 4310 ;---------------------------- 4320 WIND.LINE.OUT 4330 LDY #0 4340 WL1 4350 LDA (POINTER.A),Y 4360 BEQ WLX 4370 ; 4380 JSR ADJUST 4390 ORA REVERSE.FLAG 4400 STA (POINTER.B),Y 4410 INY 4420 BNE WL1 4430 WLX 4440 RTS 4450 ; 4460 REVERSE.FLAG 4470 .BYTE 0 4480 ; 4490 ;--------------------------- 4500 ;A Table of all known error 4510 ;code numbers. Searched top down 4520 ; 4530 ERROR.TABLE 4540 .BYTE 2,3,4,5,6 4550 .BYTE 7,8,9,10,11 4560 .BYTE 12,13,14,15,16 4570 .BYTE 17,18,19,20,21 4580 ; 4590 .BYTE 128,129,130,131,132 4600 .BYTE 133,134,135,136,137 4610 .BYTE 138,139,140,141,142 4620 .BYTE 143,144,145,146,147 4630 ; 4640 .BYTE 160,161,162,163,164 4650 .BYTE 165,166,167,168,169 4660 .BYTE 170,171 4670 NUM.ERR.ENTRIES = *-ERROR.TABLE 4680 ; 4690 ;A table of all known error 4700 ;message addresses, in the same 4710 ;order as the table above. 4720 ; 4730 ERROR.JUMP 4740 .WORD E2,E3,E4,E5 4750 .WORD E6,E7,E8,E9 4760 .WORD E10,E11,E12 4770 .WORD E13,E14,E15 4780 .WORD E16,E17,E18 4790 .WORD E19,E20,E21 4800 ; 4810 .WORD E128,E129,E130 4820 .WORD E131,E132,E133 4830 .WORD E134,E135,E136 4840 .WORD E137,E138,E139 4850 .WORD E140,E141,E142 4860 .WORD E143,E144,E145 4870 .WORD E146,E147 4880 ; 4890 .WORD E160,E161,E162 4900 .WORD E163,E164,E165 4910 .WORD E166,E167,E168 4920 .WORD E169,E170,E171 4930 ; 4940 ;---------------------------- 4950 ;The error messages themselves. 4960 ; 4970 E2 .BYTE "OUT OF MEMORY",0 4980 E3 .BYTE "VALUE ERROR",0 4990 E4 .BYTE "TOO MANY VARIABLES",0 5000 E5 .BYTE "STRING TOO LONG",0 5010 E6 .BYTE "END OF DATA",0 5020 E7 .BYTE "NUMBER TOO LARGE",0 5030 E8 .BYTE "TYPE MISMATCH",0 5040 E9 .BYTE "ARRAY DIMENSION",0 5050 E10 .BYTE "ARG STACK OVERFLOW",0 5060 E11 .BYTE "DIVIDE BY ZERO",0 5070 E12 .BYTE "LINE NOT FOUND",0 5080 E13 .BYTE "NEXT WITHOUT FOR",0 5090 E14 .BYTE "LINE TOO LONG",0 5100 E15 .BYTE "TARGET DELETED",0 5110 E16 .BYTE "RETURN TO WHERE?",0 5120 E17 .BYTE "GARBAGE IN CODE",0 5130 E18 .BYTE "NOT NUMERIC",0 5140 E19 .BYTE "PROGRAM TOO BIG",0 5150 E20 .BYTE "BAD CHANNEL #",0 5160 E21 .BYTE "NOT LOAD FORMAT",0 5170 ; 5180 E128 .BYTE "BREAK ABORT",0 5190 E129 .BYTE "CHANNEL IS OPEN",0 5200 E130 .BYTE "UNKNOWN DEVICE",0 5210 E131 .BYTE "OUTPUT ONLY",0 5220 E132 .BYTE "XIO SYNTAX ERROR",0 5230 E133 .BYTE "CHANNEL NOT OPEN",0 5240 E134 .BYTE "UNKNOWN CHANNEL",0 5250 E135 .BYTE "INPUT ONLY",0 5260 E136 .BYTE "END OF FILE",0 5270 E137 .BYTE "RECORD TRUNCATED",0 5280 E138 .BYTE "DEVICE TIMEOUT",0 5290 E139 .BYTE "COMMAND REFUSED",0 5300 E140 .BYTE "FRAMING ERROR",0 5310 E141 .BYTE "OUT OF RANGE",0 5320 E142 .BYTE "FRAME OVERRUN",0 5330 E143 .BYTE "FRAME CHECKSUM",0 5340 E144 .BYTE "DISK ERROR",0 5350 E145 .BYTE "COMPARE ERROR",0 5360 E146 .BYTE "NOT IMPLEMENTED",0 5370 E147 .BYTE "NOT ENOUGH RAM",0 5380 ; 5390 E160 .BYTE "DRIVE NUMBER",0 5400 E161 .BYTE "TOO MANY FILES",0 5410 E162 .BYTE "DISK FULL",0 5420 E163 .BYTE "UNKNOWN ERROR",0 5430 E164 .BYTE "FILE MISMATCH",0 5440 E165 .BYTE "BAD FILE NAME",0 5450 E166 .BYTE "POINT ERROR",0 5460 E167 .BYTE "FILE LOCKED",0 5470 E168 .BYTE "UNKNOWN XIO",0 5480 E169 .BYTE "DIRECTORY FULL",0 5490 E170 .BYTE "FILE NOT FOUND",0 5500 E171 .BYTE "POINT INVALID",0
Back to previous page