6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 5:42 pm

All times are UTC




Post new topic Reply to topic  [ 57 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Tue Aug 24, 2021 3:33 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
Code:
BK      .EQU *-1           ;"*" refers to the program counter

Beware that if you relocate your SWEET16 register file to another place in ZP other than $00 to $1F you will have to relocate this line somewhere else, preferably directly after a nearby LDY #0 instruction. I didn't see this small detail mentioned in the Porting Sweet 16 article here.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Last edited by barrym95838 on Tue Aug 24, 2021 3:43 pm, edited 3 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 3:34 pm 
Offline

Joined: Sun May 30, 2021 2:16 am
Posts: 375
cjs wrote:
John West wrote:
I suspect that's Wozniak's own assembler, and it looks a rather idiosyncratic one.
http://www.easy68k.com/paulrsm/6502/SW16RB.TXT has what looks like the same source code with a different (and much more standard) syntax, along with the assembled code.

That's a great find; it appears to be a machine-readable version of the listing from the original 1977-11 BYTE article by Wozniak.

The 6502.org page appears to be a reformatted copy of a file called sweet16.txt that dates back to at least 2000. That contains the material from the 1979 Call-A.P.P.L.E. Woz Pak II (which includes a version of Woz's article without source code and another article on Sweet 16 by Dick Sedgewick), bits of other documentation, and a different (and much worse) version of the source code. It's not only been reworked for whatever strange assembler doesn't use `#` to indicate immediate addressing, but also has at least two typos (loss of the SW16 entry point label and indentation of the CPR label). It does, however, add the "Following code must be contained on a single page!" comment.

My recommendation for anybody playing with this is to use the SW16RB.TXT listing and just trim off the address and data columns at the left.

I knew something was rotten in Denmark.

Jon


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 3:53 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
I can update the article on this site, with some notes and/or an appendix. I'll just quickly check with Mike first.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 3:58 pm 
Offline

Joined: Sun May 30, 2021 2:16 am
Posts: 375
BigEd wrote:
I can update the article on this site, with some notes and/or an appendix. I'll just quickly check with Mike first.

Good idea. I guess nobody has touched Sweet16 for a while?


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 4:05 pm 
Offline
User avatar

Joined: Sat Dec 01, 2018 1:53 pm
Posts: 730
Location: Tokyo, Japan
BigEd wrote:
I can update the article on this site, with some notes and/or an appendix. I'll just quickly check with Mike first.

My notes above were taken from my 8bitdev Sweet 16 source and unit tests (in progress, nothing yet pushed). Once I'm done with that, I'm happy to put in a PR for changes to the 6502.org page.

But if you want to do it, go ahead and be my guest. :-) You may find useful stuff from my source file header comments below. As well, I'd suggest that we want to grab a copy of that machine-readable version of the listing. In fact, it might be better to turn sweet16.htm into an intro page that links to all the various references, and then have separate pages (linked from the intro) for the good listing and the reformatted sweet16.txt.

Code:
;   Woz Sweet 16 Interpeter
;
;   From:
;     • Wozniak, "SWEET16: The 6502 Dream Machine," Byte vol 2 no 11 (1977-11)
;       https://archive.org/details/BYTE_Vol_02-11_1977-11_Sweet_16/page/n151
;     • Machine-readable listing from the BYTE article:
;       http://www.easy68k.com/paulrsm/6502/SW16RB.TXT
;     • Call-A.P.P.L.E. Woz Pak II (1979), pp.85-98 (PDF 87-100)
;     • http://www.fadden.com:80/dl-apple2/sweet16.txt
;     • http://www.6502.org/source/interpreters/sweet16.htm
;
;   The source code used here comes from SW16RB.TXT, presumed to be the
;   original listing. The Woz Pak II includes Woz's article, a new article
;   by Dick Sedgewick, but no source code. sweet16.txt includes both
;   articles, some further docuementation, and a very bad version of the
;   source code with odd assembler syntax (no `#` for immediate data) and
;   several typos. The original URL for it is now dead (though still on
;   archive.org); the 6502.org version is an HTML-reformatted version of
;   the text file.
;
;   Possible to-do items for this code:
;   • Make all labels local (except for the entry point)
;   • Add assembly-time check that SET through RTN+2 is on a single page.
;   • Add a set of macros to make Sweet 16 easier to use.
;
; ----------------------------------------------------------------------
;
;   The original start location for this in both the listing and the Apple
;   II Integer BASIC ROM was $F689. (It was not in the Applesoft ROM.) This
;   is commented out below, allowing clients to control the code's
;   location. Note the warning below that code from `SET` must be on a
;   single page. (A check should be added for this.)

DFB         macro
            byt ALLARGS
            endm

; ----------------------------------------------------------------------

; ***********************
; *                     *
; *   APPLE-II PSEUDO   *
; * MACHINE INTERPRETER *

...

_________________
Curt J. Sampson - github.com/0cjs


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 4:20 pm 
Offline

Joined: Sun May 30, 2021 2:16 am
Posts: 375
Here, I reformatted the whole thing.

Can someone check me?

Jon

Code:
;***********************
;*                     *
;*   APPLE-II PSEUDO   *
;* MACHINE INTERPRETER *
;*                     *
;*   COPYRIGHT 1977    *
;* APPLE COMPUTER INC  *
;*                     *
;* ALL RIGHTS RESERVED *
;*     S. WOZNIAK      *
;*                     *
;***********************
; TITLE "SWEET16 INTERPRETER"
    R0L      .EQU   $0
    R0H      .EQU   $1
    R14H     .EQU   $1D
    R15L     .EQU   $1E
    R15H     .EQU   $1F
    SW16PAG  .EQU   $F7
    SAVE     .EQU   $FF4A
    RESTORE  .EQU   $FF3F
;
    .ORG   $F689
;
SW16    JSR   SAVE       ;PRESERVE 6502 REG CONTENTS
        PLA
        STA   R15L       ;INIT SWEET16 PC
        PLA              ;FROM RETURN
        STA   R15H       ;  ADDRESS
SW16B   JSR   SW16C      ;INTERPRET AND EXECUTE
        JMP   SW16B      ;ONE SWEET16 INSTR.
SW16C   INC   R15L
        BNE   SW16D      ;INCR SWEET16 PC FOR FETCH
        INC   R15H
SW16D   LDA   #SW16PAG
        PHA              ;PUSH ON STACK FOR RTS
        LDY   #$0
        LDA   (R15L),Y   ;FETCH INSTR
        AND   #$F        ;MASK REG SPECIFICATION
        ASL              ;DOUBLE FOR TWO BYTE REGISTERS
        TAX              ;TO X REG FOR INDEXING
        LSR
        EOR   (R15L),Y   ;NOW HAVE OPCODE
        BEQ   TOBR       ;IF ZERO THEN NON-REG OP
        STX   R14H       ;INDICATE'PRIOR RESULT REG'
        LSR
        LSR              ;OPCODE*2 TO LSB'S
        LSR
        TAY              ;TO Y REG FOR INDEXING
        LDA   OPTBL-2,Y  ;LOW ORDER ADR BYTE
        PHA              ;ONTO STACK
        RTS              ;GOTO REG-OP ROUTINE
TOBR    INC   R15L
        BNE   TOBR2      ;INCR PC
        INC   R15H
TOBR2   LDA   BRTBL,X    ;LOW ORDER ADR BYTE
        PHA              ;ONTO STACK FOR NON-REG OP
        LDA   R14H       ;'PRIOR RESULT REG' INDEX
        LSR              ;PREPARE CARRY FOR BC, BNC.
        RTS              ;GOTO NON-REG OP ROUTINE
RTNZ    PLA              ;POP RETURN ADDRESS
        PLA
        JSR   RESTORE    ;RESTORE 6502 REG CONTENTS
        JMP   (R15L)     ;RETURN TO 6502 CODE VIA PC
SETZ    LDA   (R15L),Y   ;HIGH-ORDER BYTE OF CONSTANT
        STA   R0H,X
        DEY
        LDA   (R15L),Y   ;LOW-ORDER BYTE OF CONSTANT
        STA   R0L,X
        TYA              ;Y-REG CONTAINS 1
        SEC
        ADC   R15L       ;ADD 2 TO PC
        STA   R15L
        BCC   SET2
        INC   R15H
SET2    RTS
OPTBL   .lobyte   SET-1      ;1X
BRTBL   .lobyte   RTN-1      ;0
        .lobyte   LD-1       ;2X
        .lobyte   BR-1       ;1
        .lobyte   ST-1       ;3X
        .lobyte   BNC-1      ;2
        .lobyte   LDAT-1     ;4X
        .lobyte   BC-1       ;3
        .lobyte   STAT-1     ;5X
        .lobyte   BP-1       ;4
        .lobyte   LDDAT-1    ;6X
        .lobyte   BM-1       ;5
        .lobyte   STDAT-1    ;7X
        .lobyte   BZ-1       ;6
        .lobyte   POP-1      ;8X
        .lobyte   BNZ-1      ;7
        .lobyte   STPAT-1    ;9X
        .lobyte   BM1-1      ;8
        .lobyte   ADD-1      ;AX
        .lobyte   BNM1-1     ;9
        .lobyte   SUB-1      ;BX
        .lobyte   BK-1       ;A
        .lobyte   POPD-1     ;CX
        .lobyte   RS-1       ;B
        .lobyte   CPR-1      ;DX
        .lobyte   BS-1       ;C
        .lobyte   INR-1      ;EX
        .lobyte   NUL-1      ;D
        .lobyte   DCR-1      ;FX
        .lobyte   NUL-1      ;E
        .lobyte   NUL-1      ;UNUSED
        .lobyte   NUL-1      ;F
;
;   NB: The code from `SET` must be on a single page.
;
SET     BPL   SETZ       ;ALWAYS TAKEN
LD      LDA   R0L,X
BK      .EQU   *-1
        STA   R0L
        LDA   R0H,X      ;MOVE RX TO R0
        STA   R0H
        RTS
ST      LDA   R0L
        STA   R0L,X      ;MOVE R0 TO RX
        LDA   R0H
        STA   R0H,X
        RTS
STAT    LDA   R0L
STAT2   STA   (R0L,X)    ;STORE BYTE INDIRECT
        LDY   #$0
STAT3   STY   R14H       ;INDICATE R0 IS RESULT NEG
INR     INC   R0L,X
        BNE   INR2       ;INCR RX
        INC   R0H,X
INR2    RTS
LDAT    LDA   (R0L,X)    ;LOAD INDIRECT (RX)
        STA   R0L        ;TO R0
        LDY   #$0
        STY   R0H        ;ZERO HIGH-ORDER R0 BYTE
        BEQ   STAT3      ;ALWAYS TAKEN
POP     LDY   #$0        ;HIGH ORDER BYTE = 0
        BEQ   POP2       ;ALWAYS TAKEN
POPD    JSR   DCR        ;DECR RX
        LDA   (R0L,X)    ;POP HIGH ORDER BYTE @RX
        TAY              ;SAVE IN Y-REG
POP2    JSR   DCR        ;DECR RX
        LDA   (R0L,X)    ;LOW-ORDER BYTE
        STA   R0L        ;TO R0
        STY   R0H
POP3    LDY   #$0        ;INDICATE R0 AS LAST RESULT REG
        STY   R14H
        RTS
LDDAT   JSR   LDAT       ;LOW-ORDER BYTE TO R0, INCR RX
        LDA   (R0L,X)    ;HIGH-ORDER BYTE TO R0
        STA   R0H
        JMP   INR        ;INCR RX
STDAT   JSR   STAT       ;STORE INDIRECT LOW-ORDER
        LDA   R0H        ;BYTE AND INCR RX.  THEN
        STA   (R0L,X)    ;STORE HIGH-ORDER BYTE.
        JMP   INR        ;INCR RX AND RETURN
STPAT   JSR   DCR        ;DECR RX
        LDA   R0L
        STA   (R0L,X)    ;STORE R0 LOW BYTE @RX
        JMP   POP3       ;INDICATE R0 AS LAST RSLT REG
DCR     LDA   R0L,X
        BNE   DCR2       ;DECR RX
        DEC   R0H,X
DCR2    DEC   R0L,X
        RTS
SUB     LDY   #$0        ;RESULT TO R0
CPR     SEC              ;NOTE Y-REG = 13*2 FOR CPR
        LDA   R0L
        SBC   R0L,X
        STA   R0L,Y      ;R0-RX TO RY
        LDA   R0H
        SBC   R0H,X
SUB2    STA   R0H,Y
        TYA              ;LAST RESULT REG*2
        ADC   #$0        ;CARRY TO LSB
        STA   R14H
        RTS
ADD     LDA   R0L
        ADC   R0L,X
        STA   R0L        ;R0+RX TO R0
        LDA   R0H
        ADC   R0H,X
        LDY   #$0        ;R0 FOR RESULT
        BEQ   SUB2       ;FINISH ADD
BS      LDA   R15L       ;NOTE X-REG IS 12*2!
        JSR   STAT2      ;PUSH LOW PC BYTE VIA R12
        LDA   R15H
        JSR   STAT2      ;PUSH HIGH-ORDER PC BYTE
BR      CLC
BNC     BCS   BNC2       ;NO CARRY TEST
BR1     LDA   (R15L),Y   ;DISPLACEMENT BYTE
        BPL   BR2
        DEY
BR2     ADC   R15L       ;ADD TO PC
        STA   R15L
        TYA
        ADC   R15H
        STA   R15H
BNC2    RTS
BC      BCS   BR
        RTS
BP      ASL              ;DOUBLE RESULT-REG INDEX
        TAX              ;TO X REG FOR INDEXING
        LDA   R0H,X      ;TEST FOR PLUS
        BPL   BR1        ;BRANCH IF SO
        RTS
BM      ASL              ;DOUBLE RESULT-REG INDEX
        TAX
        LDA   R0H,X      ;TEST FOR MINUS
        BMI   BR1
        RTS
BZ      ASL              ;DOUBLE RESULT-REG INDEX
        TAX
        LDA   R0L,X      ;TEST FOR ZERO
        ORA   R0H,X      ;(BOTH BYTES)
        BEQ   BR1        ;BRANCH IF SO
        RTS
BNZ     ASL              ;DOUBLE RESULT-REG INDEX
        TAX
        LDA   R0L,X      ;TEST FOR NON-ZERO
        ORA   R0H,X      ;(BOTH BYTES)
        BNE   BR1        ;BRANCH IF SO
        RTS
BM1     ASL              ;DOUBLE RESULT-REG INDEX
        TAX
        LDA   R0L,X      ;CHECK BOTH BYTES
        AND   R0H,X      ;FOR $FF (MINUS 1)
        EOR   #$FF
        BEQ   BR1        ;BRANCH IF SO
        RTS
BNM1    ASL              ;DOUBLE RESULT-REG INDEX
        TAX
        LDA   R0L,X
        AND   R0H,X      ;CHECK BOTH BYTES FOR NO $FF
        EOR   #$FF
        BNE   BR1        ;BRANCH IF NOT MINUS 1
NUL     RTS
RS      LDX   #$18       ;12*2 FOR R12 AS STACK POINTER
        JSR   DCR        ;DECR STACK POINTER
        LDA   (R0L,X)    ;POP HIGH RETURN ADDRESS TO PC
        STA   R15H
        JSR   DCR        ;SAME FOR LOW-ORDER BYTE
        LDA   (R0L,X)
        STA   R15L
        RTS
RTN     JMP   RTNZ


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 4:37 pm 
Offline
User avatar

Joined: Sat Dec 01, 2018 1:53 pm
Posts: 730
Location: Tokyo, Japan
BTW, it turns out that the source code as given has a dependency on the SAVE and RESTORE routines in the Apple II/II+ Monitor ROM. These should save and restore A, X, Y and the status register, and need not be reentrant. I think that these can simply jump to routines that RTS, so long as you're not concerned with preserving the registers after a Sweet 16 call, but I've not yet tested this.

_________________
Curt J. Sampson - github.com/0cjs


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 4:47 pm 
Offline

Joined: Sun May 30, 2021 2:16 am
Posts: 375
cjs wrote:
BTW, it turns out that the source code as given has a dependency on the SAVE and RESTORE routines in the Apple II/II+ Monitor ROM. These should save and restore A, X, Y and the status register, and need not be reentrant. I think that these can simply jump to routines that RTS, so long as you're not concerned with preserving the registers after a Sweet 16 call, but I've not yet tested this.

I used this:

Code:
 ;-------------------------------
 ACC    .EQU $20
 XREG   .EQU $21
 YREG   .EQU $22
 STATUS .EQU $23
 ;
 SAVE16
    STA ACC
    STX XREG
    STY YREG
    PHP
    PLA
    STA STATUS
    CLD
    RTS
 ;------------------------------
 RESTORE16
    LDA STATUS
    PHA
    LDA ACC
    LDX XREG
    LDY YREG
    PLP
    RTS
;


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 4:58 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8504
Location: Midwestern USA
...and if all else fails and you are desperate for 16-bit operations, you could consider the 65C816... :D

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 5:32 pm 
Offline

Joined: Sun May 30, 2021 2:16 am
Posts: 375
BigDumbDinosaur wrote:
...and if all else fails and you are desperate for 16-bit operations, you could consider the 65C816... :D

Lol - and what fun would that be? :lol:

Jon


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 6:02 pm 
Offline
User avatar

Joined: Sat Dec 01, 2018 1:53 pm
Posts: 730
Location: Tokyo, Japan
One more thing I just came across: the Woz Pak II also includes another interesting reprint from Dr. Dobb's, a more extended Sweet 16 program called Lazarus (by Andy Hertzfeld) that recovers deleted Integer BASIC programs. It's probably an especially good example of Sweet 16 use since it involves a lot of 16-bit arithmetic; I am guessing that the 175 byte program would be much, much longer if it were 6502 code.

The Programmer's Aid #1 ROM also used Sweet 16 for various tools (Renumber, Append, and Relocate).

_________________
Curt J. Sampson - github.com/0cjs


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 6:36 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
Off-topic: AIUI, Woz Integer BASIC programs were a bit unique in that they stored variables and arrays from LOMEM up and program code from HIMEM down, so the two never touched each other unless you were out of RAM. His "HP"-style strings were not auto-dynamically allocated, so there was no need for garbage collection. This set-up allowed easy CHAINing of programs without disturbing the workspace. His LIST command was not only quite eccentric, but also more than a bit sophisticated.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Last edited by barrym95838 on Tue Aug 24, 2021 7:03 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 7:02 pm 
Offline
User avatar

Joined: Sat Dec 01, 2018 1:53 pm
Posts: 730
Location: Tokyo, Japan
barrym95838 wrote:
Code:
BK      .EQU *-1           ;"*" refers to the program counter

Beware that if you relocate your SWEET16 register file to another place in ZP other than $00 to $1F you will have to relocate this line somewhere else, preferably directly after a nearby LDY #0 instruction. I didn't see this small detail mentioned in the Porting Sweet 16 article here.

Oh, that's a really nice catch! Such risks to save a single byte, though I guess it wasn't such a risk for code in ROM.

Anyway, can that byte be any handy zero byte, or are there any special conditions that it must meet? It looks to me as if the current implementation is not going to give you any useful information about the break point that you wouldn't get from any other random zero byte within the SW16 code. (You're always going to have to use R15 to figure out where the SW16 interpreter was actually executing, if you need that, and restart at some point other than the address after the BRK if you want to continue.)

Perhaps the byte at $F6A2 would work for this, since it's an LDY #$0, rather than being connected to register location?

_________________
Curt J. Sampson - github.com/0cjs


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 7:07 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
cjs wrote:
Perhaps the byte at $F6A2 would work for this, since it's an LDY #$0, rather than being connected to register location?

No, it has to be in the same page that it was. There should be a couple of LDY #0s in the $F7xx area that'll do.

Off-topic again: RIP Charlie Watts. You were the cat's meow!

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 24, 2021 7:20 pm 
Offline
User avatar

Joined: Sat Dec 01, 2018 1:53 pm
Posts: 730
Location: Tokyo, Japan
Jmstein7 wrote:
I'm going to re-write it with more contemporary directives and see if I can get it to work, using what you guys have proffered. I'll post the results here. If anyone wants to give it a shot, too, and do the same, I'm curious how it goes. Let me know...

After a wrong turn with the sweet16.txt source, I dropped the SW16RB.TXT source into the src/woz/ subdir of my 8bitdev repo, tweaked it to build with Macroassembler AS, and set up a couple of unit tests. One test just sets up a Sweet 16 RTN and runs the interpreter on it, mainly to make sure that it's correctly built and loaded into the simulator. The second test is the memory copy example given in the Sedgewick article.

Assuming the overall 8bitdev framework is working for you, it's pretty simple to add a new test or modify an existing text to run whatever Sweet 16 code you care to and examine the results on registers or memory. If anybody's playing with this (or wanting to play with it) and having difficulty, drop me a PM and I'll help you out with any problems you're having.

_________________
Curt J. Sampson - github.com/0cjs


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 57 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: