!!!Sweet 16 for MAC/65 Atari 8bit General Information Author: Steve "Woz" Wozniak \\ Assembler: Mac/65 \\ Published: 1977 \\ see also Original [Sweet 16] This is a port of the Sweet 16 interpreter to the 8bit ATARI. !! Diffs * The ATARI uses the zero page registers at $E0-$FF instead of $00-$1F * the "save" and "restore" routines are not in ROM, but in the source !! Mac/65 Source {{{ 1010 *************************** 1020 * * 1030 * APPLE II PSEUDO MACHINE * 1040 * INTERPRETER * 1050 * * 1060 * COPYRIGHT (C) 1977 * 1070 * APPLE COMPUTER INC. * 1080 * * 1090 * STEVE WOZNIAK * 1100 * * 1110 *************************** 1120 * TITLE: SWEET 16 INTERPRETER 1130 ; 1131 *= $7889 1132 ; 1140 R0L = $E0 1150 R0H = $E1 1160 R14H = $FD 1170 R15L = $FE 1180 R15H = $FF 1190 ; 1220 ; 1230 ; PRESERVE 6502 REG CONTENT 1240 ; 1250 SW16 JSR SAVE 1260 ; 1270 ; INIT SWEET16 PC 1280 ; FROM RETURN ADDRESS 1290 ; 1300 SW16A PLA 1310 STA R15L 1320 PLA 1330 STA R15H 1340 ; 1350 ; INTERPRET AND EXECUTE 1360 ; ONE SWEET16 INSTRUCTION 1370 ; 1380 SW16B JSR SW16C 1390 JMP SW16B 1400 ; 1410 ; INCREMENT SWEET16 PC 1420 ; FOR FETCH 1430 ; 1440 SW16C INC R15L 1450 BNE SW16D 1460 INC R15H 1470 ; 1480 ; COMMON HIG BZTE FOR ALL 1490 ; ROUTINES, PUSH ON STACK FOR 1500 ; RTS 1510 SW16D LDA # >SET 1520 PHA 1530 ; 1540 ; FETCH INSTRUCTION 1550 ; 1560 LDY #$00 1570 LDA (R15L),Y 1580 ; 1590 ; MASK REGISTER SPECIFICATION 1600 ; 1610 AND #$0F 1620 ; 1630 ; DOUBLE FOR TWO BYTE REGISTERS 1640 ; 1650 ASL A 1660 ; 1670 ; TO X REGISTER FOR INDEXING 1680 ; 1690 TAX 1700 LSR A 1710 ; 1720 ; NOW HAVE OPCODE 1730 ; 1740 EOR (R15L),Y 1750 ; 1760 ; IF ZERO THEN NO REG OPCODE 1770 ; 1780 BEQ TOBR 1790 ; 1800 ; INDICATE PRIOR RESULT REG 1810 ; 1820 STX R14H 1830 ; 1840 ; OPCODE * 2 TO LSB'S 1850 ; 1860 LSR A 1870 LSR A 1880 LSR A 1890 ; 1900 ; TO Y REGISTER FOR INDEXING 1910 ; 1920 TAY 1930 ; 1940 ; LOW ORDER ADR BYTE ON STACK 1950 ; 1960 LDA OPTBL-2,Y 1970 PHA 1980 ; 1990 ; GOTO REG-OPCODE ROUTINE 2000 ; 2010 RTS 2020 ; 2030 ; INCREMENT PC 2040 ; 2050 TOBR 2051 INC R15L 2060 BNE TOBR2 2070 INC R15H 2080 ; 2090 ; LOW ORDER ADR BYTE ONTO 2100 ; STACK FOR NON-REG OPCODE 2110 ; 2120 TOBR2 LDA BRTBL,X 2130 PHA 2140 ; 2150 ; PRIOR RESULT REG INDEX 2160 ; 2170 LDA R14H 2180 ; 2190 ; PREPARE CARRY FOR BC. BNC. 2200 ; 2210 LSR A 2220 ; 2230 ; GOTO NON-REG OPCODE ROUTINE 2240 ; 2250 RTS 2260 ; 2270 ; RETURN TO 6502 MODE ROUTINE 2280 ; 2290 ; POP RETURN ADDRESS 2300 ; 2310 RTNZ PLA 2320 PLA 2330 ; 2340 ; RESTORE 6502 REG CONTENT 2350 ; 2360 JSR RESTORE 2370 ; 2380 ; RETURN TO 6502 CODE VIA PC 2390 ; 2400 JMP (R15L) 2410 ; 2420 ; SET REGISTER ROUTINE 2430 ; 2440 ; GET HIGH BYTE OF CONSTANT 2450 ; 2460 SETZ LDA (R15L),Y 2470 STA R0H,X 2480 DEY 2490 ; 2500 ; GET LOW BYTE OF CONSTANT 2510 ; 2520 LDA (R15L),Y 2530 STA R0L,X 2540 ; 2550 ; Y REG CONTAINS 1 2560 ; 2570 TYA 2580 ; 2590 ; ADD 2 TO PC 2600 ; 2610 SEC 2620 ADC R15L 2630 STA R15L 2640 BCC SET2 2650 INC R15H 2660 SET2 RTS 2670 ; 2680 ; OPCODE TABLE 2690 ; 2700 OPTBL .BYTE <SET-1 ; 1X 2710 BRTBL .BYTE <RTN-1 ; 0 2720 .BYTE <LD-1 ; 2X 2730 .BYTE <BR-1 ; 1 2740 .BYTE <ST-1 ; 3X 2750 .BYTE <BNC-1 ; 2 2760 .BYTE <LDAT-1 ; 4X 2770 .BYTE <BC-1 ; 3 2780 .BYTE <STAT-1 ; 5X 2790 .BYTE <BP-1 ; 4 2800 .BYTE <LDDAT-1 ; 6X 2810 .BYTE <BM-1 ; 5 2820 .BYTE <STDAT-1 ; 7X 2830 .BYTE <BZ-1 ; 6 2840 .BYTE <POP-1 ; 8X 2850 .BYTE <BNZ-1 ; 7 2860 .BYTE <STPAT-1 ; 9X 2870 .BYTE <BM1-1 ; 8 2880 .BYTE <ADD-1 ; AX 2890 .BYTE <BNM1-1 ; 9 2900 .BYTE <SUB-1 ; BX 2910 .BYTE <BK-1 ; A 2920 .BYTE <POPD-1 ; CX 2930 .BYTE <RS-1 ; B 2940 .BYTE <CPR-1 ; DX 2950 .BYTE <BS-1 ; C 2960 .BYTE <INR-1 ; EX 2970 .BYTE <NUL-1 ; D 2980 .BYTE <DCR-1 ; FX 2990 .BYTE <NUL-1 ; E 3000 .BYTE <NUL-1 ; UNUSED 3010 .BYTE <NUL-1 ; F 3020 ; 3030 ; THE FOLLOWING CODE MUST 3040 ; BE CONTAINED IN A SINGLE PAGE 3050 ; 3060 SET 3061 JMP SETZ ; ALWAYS 3070 LD 3071 LDA R0L,X 3080 BK = LD+1 3090 STA R0L 3100 ; 3110 ; MOV RX TO R0 3120 ; 3130 LDA R0H,X 3140 STA R0H 3150 RTS 3160 ; 3170 ST LDA R0L 3180 ; 3190 ; MOV R0 TO RX 3200 ; 3210 STA R0L,X 3220 LDA R0H 3230 STA R0H,X 3240 RTS 3250 ; 3260 ; STORE BYTE INDEIRECT 3270 ; 3280 STAT LDA R0L 3290 STAT2 STA (R0L,X) 3300 LDY #$00 3310 ; 3320 ; INDICATE R0 IS RESULT NEG 3330 ; 3340 STAT3 STY R14H 3350 INR INC R0L,X 3360 BNE INR2 ; INC RX 3370 INC R0H,X 3380 INR2 RTS 3390 ; 3400 ; LOAD INDIRECT (RX) TO R0 3410 ; 3420 LDAT LDA (R0L,X) 3430 STA R0L 3440 ; 3450 ; ZERO HIGH ORDER R0 BYTE 3460 ; 3470 LDY #$00 3480 STY R0H 3490 BEQ STAT3 ; ALWAYS 3500 ; 3510 ; HIGH ORDER BYTE = 0 3520 ; 3530 POP LDY #$00 3540 BEQ POP2 ; ALWAYS 3550 POPD JSR DCR ; DECR RX 3560 ; 3570 ; POP HIGH ORDER BYTE @RX 3580 ; AND SAV IN Y REG 3590 ; 3600 LDA (R0L,X) 3610 TAY 3620 POP2 JSR DCR ; DECR RX 3630 ; 3640 ; LOW ORDER BYTE TO R0 3650 ; 3660 LDA (R0L,X) 3670 STA R0L 3680 STY R0H 3690 ; 3700 ; INDICATE R0 AS LAST RES. REG 3710 ; 3720 POP3 LDY #$00 3730 STY R14H 3740 RTS 3750 ; 3760 ; LOW ORDER BYTE TO R0, INC RX 3770 ; 3780 LDDAT JSR LDAT 3790 ; 3800 ; HIGH ORDER BYTE TO R0 3810 LDA (R0L,X) 3820 STA R0H 3830 JMP INR ; INC RX 3840 ; 3850 ; STORE INDIRECT LOW ORDER 3860 ; BYTE AND INC RX THEN 3870 ; STORE HIGH ORDER BYTE, 3880 ; INC RX AND RETURN 3890 ; 3900 STDAT JSR LDAT 3910 LDA R0H 3920 STA (R0L,X) 3930 JMP INR 3940 STPAT JSR DCR ; DEC RX 3950 LDA R0L 3960 ; 3970 ; STORE R0 LOW BYTE @RX 3980 ; 3990 STA (R0L,X) 4000 ; 4010 ; INDICATE R0 AS LAST RES REG 4020 ; 4030 JMP POP3 4040 ; 4050 DCR LDA R0L,X 4060 BNE DCR2 ; DEC RX 4070 DEC R0H,X 4080 DCR2 DEC R0L,X 4090 RTS 4100 ; 4110 ; RESULT TO R0 4120 ; 4130 SUB LDY #$00 4140 ; 4150 ; NOTE Y REG = 13 * 2 FOR CPR 4160 ; 4170 CPR SEC 4180 LDA R0L 4190 SBC R0L,X 4200 STA R0L,Y ; RY=R0-RX 4210 LDA R0H 4220 SBC R0H,X 4230 SUB2 STA R0H,Y 4240 ; 4250 ; LAST RESULT REG * 2 4260 ; 4270 TYA 4280 ; 4290 ; CARRY TO LSB 4300 ; 4310 ADC #$00 4320 STA R14H 4330 RTS 4340 ; 4350 ADD LDA R0L 4360 ADC R0L,X 4370 STA R0L ; R0=RX+R0 4380 LDA R0H 4390 ADC R0H,X 4400 ; 4410 ; R0 FOR RESULT 4420 ; 4430 LDY #$00 4440 ; FINISH ADD 4450 BEQ SUB2 4460 ; 4470 ; NOTE X REG IS 12 * 2 ! 4480 ; 4490 BS LDA R15L 4500 ; 4510 ; PUSH LOW PC BYTE VIA R12 4520 ; 4530 JSR STAT2 4540 LDA R15H 4550 ; 4560 ; PUSH HIGH PC BYTE 4570 ; 4580 JSR STAT2 4590 BR CLC 4600 BNC BCS BNC2 ; NO CARRY TEST 4610 ; 4620 ; DISPLACEMENT BYTE 4630 ; 4640 BR1 LDA (R15L),Y 4650 BPL BR2 4660 DEY 4670 ; 4680 ; ADD TO PC 4690 ; 4700 BR2 ADC R15L 4710 STA R15L 4720 TYA 4730 ADC R15H 4740 STA R15H 4750 BNC2 RTS 4760 BC BCS BR 4770 RTS 4780 ; 4790 ; DOUBLE RESULT REG INDEX 4800 ; 4810 BP ASL A 4820 ; 4830 ; TO X REG FOR INDEX 4840 ; 4850 TAX 4860 ; TEST FOR PLUS, BRANCH IF SO 4870 ; 4880 LDA R0H,X 4890 BPL BR1 4900 RTS 4910 ; 4920 ; DOUBLE RESULT REG INDEX 4930 ; 4940 BM ASL A 4950 TAX 4960 ; 4970 ; TEST FOR MINUS 4980 ; 4990 LDA R0H,X 5000 BMI BR1 5010 RTS 5020 ; 5030 ; DOUBLE RESULT REG INDEX 5040 ; 5050 BZ ASL A 5060 TAX 5070 ; 5080 ; TEST FOR ZERO (BOTH BYTES) 5090 ; 5100 LDA R0L,X 5110 ORA R0H,X 5120 BEQ BR1 5130 RTS 5140 ; 5150 ; DOUBLE RESULT REG INDEX 5160 ; 5170 BNZ ASL A 5180 TAX 5190 ; 5200 ; TEST FOR NON-ZERO (BOTH) 5210 ; 5220 LDA R0L,X 5230 ORA R0H,X 5240 BNE BR1 5250 RTS 5260 ; 5270 ; DOUBLE RESULT REG INDEX 5280 ; 5290 BM1 ASL A 5300 TAX 5310 ; 5320 ; TEST FOR $FF (-1) BOTH BYTES 5330 ; 5340 LDA R0L,X 5350 AND R0H,X 5360 EOR #$FF 5370 BEQ BR1 5380 RTS 5390 ; 5400 ; DOUBLE RESULT REG 5410 ; 5420 BNM1 ASL A 5430 TAX 5440 ; 5450 ; TEST FOR NO $FF 5460 ; 5470 LDA R0L,X 5480 AND R0H,X 5490 EOR #$FF 5500 BNE BR1 5510 NUL RTS 5520 ; 12*2 FOR R12 AS STACK POINTER 5530 ; 5540 RS LDX #$18 5550 ; 5560 ; DECR STACK POINTER 5570 ; 5580 JSR DCR 5590 ; 5600 ; POP HIGHRETURN ADDRESS TO PC 5610 ; 5620 LDA (R0L,X) 5630 STA R15H 5640 ; 5650 ; SAME WITH LOW ORDER BYTE 5660 ; 5670 JSR DCR 5680 LDA (R0L,X) 5690 STA R15L 5700 RTS 5710 RTN JMP RTNZ 5720 ;------------------------------ 5730 SAVE 5740 STA ACC 5750 STX XREG 5760 STY YREG 5770 PHP 5780 PLA 5790 STA STATUS 5800 CLD 5810 RTS 5820 ;------------------------------ 5830 RESTORE LDA STATUS 5840 PHA 5850 LDA ACC 5860 LDX XREG 5870 LDY YREG 5880 PLP 5890 RTS 5900 ;------------------------------- 5910 ACC .BYTE 0 5920 XREG .BYTE 0 5930 YREG .BYTE 0 5940 STATUS .BYTE 0 5950 ;------------------------------ 5960 TEST 5970 JSR SW16A 5980 .BYTE $11,$00,$F0 ; SET R1 5990 .BYTE $12,$00,$40 ; SET R2 6000 .BYTE $13,$00,$02 ; SET R3 6010 .BYTE $41 ; LD @R1 6020 .BYTE $52 ; ST @R2 6030 .BYTE $F3 ; DCR R3 6040 .BYTE $07,$FB ; BNZ -4 6050 .BYTE $00 ; RTN 6060 RTS 6070 ;------------------------------ }}}