From 31d466f0bd6f7aad3859facc28e6c42422d61345 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Wed, 12 Aug 2020 20:40:56 -0700 Subject: [PATCH] Update some Apple II definitions Added a bunch of Applesoft entry points, and updated the F8ROM definitions. Added a visualizer for Applesoft shape table shapes that are not part of an actual shape table. --- SourceGen/RuntimeData/Apple/Applesoft.sym65 | 36 ++++++++++++++++++-- SourceGen/RuntimeData/Apple/F8-ROM.sym65 | 14 ++++++-- SourceGen/RuntimeData/Apple/VisShapeTable.cs | 31 +++++++++++++++-- 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/SourceGen/RuntimeData/Apple/Applesoft.sym65 b/SourceGen/RuntimeData/Apple/Applesoft.sym65 index 90a4d64..8f7b130 100644 --- a/SourceGen/RuntimeData/Apple/Applesoft.sym65 +++ b/SourceGen/RuntimeData/Apple/Applesoft.sym65 @@ -74,10 +74,42 @@ BAS_FRMEVL @ $DD7B ;eval expr at TXTPTR (num/str), result into FAC BAS_SYN_ERROR @ $DEC9 ;throw SYNTAX ERROR BAS_CHKCOM @ $DEBE ;checks TXTPTR for comma BAS_ILLQ_ERROR @ $E199 ;throw ILLEGAL QUANTITY ERROR -BAS_GETADR @ $E752 ;convert FAC to 2-byte integer in LINNUM +BAS_GIVAYF @ $E2F2 ;convert 16-bit (A,Y) to float, store in FAC +BAS_SNGFLT @ $E301 ;convert 8-bit int (Y) to FLOAT BAS_GETBYT @ $E6F8 ;gets byte, in X/FACLO -BAS_QINT @ $EBF2 ;converts FP value in FAC to int in FAC+1..FAC+4 +BAS_GETADR @ $E752 ;convert FAC to 2-byte integer in LINNUM +BAS_FSUB @ $E7A7 ;FAC = (Y,A) - FAC +BAS_FADD @ $E7BE ;FAC = (Y,A) + FAC +BAS_CON_ONE @ $E913 ;constant value 1.0 +BAS_FMULT @ $E97F ;FAC = (Y,A) * FAC +BAS_LOAD_ARG_FROM_YA @ $E9E3 ;unpack 5-byte val at (Y,A) into ARG +BAS_MUL10 @ $EA39 ;multiply FAC by 10 +BAS_CON_TEN @ $EA50 ;constant value 10.0 +BAS_FDIV @ $EA66 ;FAC = (Y,A) / FAC +BAS_LOAD_FAC_FROM_YA @ $EAF9 ;unpack 5-byte val at (Y,A) into FAC +BAS_STORE_FAC_AT_YX_ROUNDED @ $EB2B ;round FAC, store at (Y,X) +BAS_SIGN @ $EB82 ;test FAC sign; <,=,> 0 -> A={-1,0,1} +BAS_FLOAT @ $EB93 ;convert value in A to float in FAC +BAS_ABS @ $EBAF ;changes sign of FAC to + +BAS_FCOMP @ $EBB2 ;cmp (Y,A) with FAC; <,=,> -> A={1,0,-1} +BAS_QINT @ $EBF2 ;convert FAC to big-endian int in FAC+1..FAC+4 +BAS_INT @ $EC23 ;FAC = floor(FAC) +BAS_LINPRT @ $ED24 ;print float at (A,X) as decimal integer +BAS_PRINT_FAC @ $ED2E ;print FAC to screen +BAS_CON_HALF @ $EE64 ;constant value 0.5 +BAS_FPWRT @ $EE97 ;compute exponentiation +BAS_NEGOP @ $EED0 ;negate value in FAC +BAS_RND @ $EFAE ;generate random number +BAS_CON_PI_HALF @ $F066 ;constant value PI/2 +BAS_CON_PI_DOUB @ $F06B ;constant value PI*2 +BAS_QUARTER @ $F070 ;constant value 0.25 +BAS_HGR @ $F3E2 ;switch to hi-res mixed-mode and clear +BAS_HPOSN @ $F411 ;set hi-res position; horiz=(Y,X) vert=A +BAS_HPLOT0 @ $F457 ;plot point; horiz=(Y,X), vert=A +BAS_HGLIN @ $F53A ;draw line from last point to (A,X),Y +BAS_DRAW0 @ $F601 ;draw a shape from addr (Y,X) BAS_HFNS @ $F6B9 ;get hi-res x/y for hplot +BAS_HCOLOR @ $F6E9 ;set hi-res color ; ; Applesoft BASIC tokens. diff --git a/SourceGen/RuntimeData/Apple/F8-ROM.sym65 b/SourceGen/RuntimeData/Apple/F8-ROM.sym65 index 3007a97..057a0e4 100644 --- a/SourceGen/RuntimeData/Apple/F8-ROM.sym65 +++ b/SourceGen/RuntimeData/Apple/F8-ROM.sym65 @@ -7,6 +7,7 @@ *SYNOPSIS Symbols from the Apple II monitor ROM +; zero page usage MON_WNDLEFT @ $20 ;left column of scroll window MON_WNDWDTH @ $21 ;width of scroll window MON_WNDTOP @ $22 ;top of scroll window @@ -43,6 +44,7 @@ MON_A5H @ $45 ;general purpose MON_RNDL @ $4E ;low byte of KEYIN "random" value MON_RNDH @ $4F ;high byte of KEYIN "random" value +; page 3 vectors MON_BRKV @ $03F0 2 ;address of BRK handler MON_SOFTEVEC @ $03F2 2 ;address of RESET handler MON_PWREDUP @ $03F4 ;power-up RESET checksum @@ -50,6 +52,7 @@ MON_USRADDR @ $03F8 3 ;jump to function that handles monitor Ctrl-Y MON_NMIVEC @ $03FB 3 ;jump to function that handles NMI MON_IRQADDR @ $03FE 2 ;address of IRQ handler +; monitor entry points MON_PLOT @ $F800 ;lo-res plot at X=Y-reg, Y=Acc MON_PLOT1 @ $F80E ;lo-res plot at X=Y-reg, Y per GBASL/H MON_HLINE @ $F819 ;lo-res horiz line at Y=Acc with X from $2c @@ -118,7 +121,7 @@ MON_NXTA1 @ $FCBA ;increment A1; set carry if A1 >= A2 before inc MON_HEADR @ $FCC9 ;write cassette sync MON_WRTAPE @ $FCE5 ;casssette write MON_RD2BIT @ $FCFA ;cassette read -MON_RDKEY @ $FD0C ;read key +MON_RDKEY @ $FD0C ;read key from input device via $38-39 MON_FD10 @ $FD10 MON_RDKEY1 @ $FD18 MON_KEYIN @ $FD1B ;get next key input from keyboard hardware @@ -132,8 +135,8 @@ MON_CROUT @ $FD8E ;print a carriage return MON_PRA1 @ $FD92 ;print CR, then hex of A1H/A1L, then minus sign MON_PRBYTE @ $FDDA ;print Acc as two-digit hex number MON_PRHEX @ $FDE3 ;print right nibble of Acc as single hex digit -MON_COUT @ $FDED ;print Acc to output device -MON_COUT1 @ $FDF0 +MON_COUT @ $FDED ;print Acc to output device via $36-37 +MON_COUT1 @ $FDF0 ;print Acc to screen MON_COUTZ @ $FDF6 MON_IDROUTINE @ $FE1F MON_MOVE @ $FE2C ;move bytes from A1 to A4 until A1=A2 @@ -163,3 +166,8 @@ MON_GETNUM @ $FFA7 MON_NXTCHR @ $FFAD ;part of GETLN input loop MON_TOSUB @ $FFBE MON_ZMODE @ $FFC7 + +; locations defined by the 6502 +MON_6502_NMI @ $FFFA ;6502 NMI vector +MON_6502_RESET @ $FFFC ;6502 reset vector +MON_6502_IRQ @ $FFFE ;6502 IRQ vector diff --git a/SourceGen/RuntimeData/Apple/VisShapeTable.cs b/SourceGen/RuntimeData/Apple/VisShapeTable.cs index 62a492f..e59043e 100644 --- a/SourceGen/RuntimeData/Apple/VisShapeTable.cs +++ b/SourceGen/RuntimeData/Apple/VisShapeTable.cs @@ -41,6 +41,11 @@ namespace RuntimeData.Apple { /// CCBBBAAA. AAA and BBB specify a direction (up/right/down/left) and whether or /// not to plot a point. CC cannot specify whether to plot and cannot move up (a 00 /// in CC means "do nothing"). + /// + /// TODO: optionally render as it would on the hi-res screen. Some shapes draw with + /// HCOLOR=white but use alternating vertical lines to render multiple colors. + /// TODO: support ROT, using Applesoft-style ugly rotation handling. Could also support + /// SCALE but that's only interesting w.r.t. hi-res color changes. /// public class VisShapeTable : MarshalByRefObject, IPlugin, IPlugin_Visualizer { // IPlugin @@ -52,6 +57,7 @@ namespace RuntimeData.Apple { // Visualization identifiers; DO NOT change or projects that use them will break. private const string VIS_GEN_SHAPE_TABLE = "apple2-shape-table"; + private const string VIS_GEN_SHAPE_TABLE_SHAPE = "apple2-shape-table-shape"; private const string P_OFFSET = "offset"; private const string P_INDEX = "index"; @@ -65,6 +71,11 @@ namespace RuntimeData.Apple { new VisParamDescr("Image index", P_INDEX, typeof(int), 0, 256, 0, 0), }), + new VisDescr(VIS_GEN_SHAPE_TABLE_SHAPE, "Apple II Shape Table Shape", VisDescr.VisType.Bitmap, + new VisParamDescr[] { + new VisParamDescr("File offset (hex)", + P_OFFSET, typeof(int), 0, 0x00ffffff, VisParamDescr.SpecialMode.Offset, 0), + }), }; @@ -93,14 +104,16 @@ namespace RuntimeData.Apple { ReadOnlyDictionary parms) { switch (descr.Ident) { case VIS_GEN_SHAPE_TABLE: - return GenerateBitmap(parms); + return GenerateBitmapFromTable(parms); + case VIS_GEN_SHAPE_TABLE_SHAPE: + return GenerateBitmapFromShape(parms); default: mAppRef.ReportError("Unknown ident " + descr.Ident); return null; } } - private IVisualization2d GenerateBitmap(ReadOnlyDictionary parms) { + private IVisualization2d GenerateBitmapFromTable(ReadOnlyDictionary parms) { int offset = Util.GetFromObjDict(parms, P_OFFSET, 0); int shapeIndex = Util.GetFromObjDict(parms, P_INDEX, 0); @@ -123,8 +136,20 @@ namespace RuntimeData.Apple { } int shapeOffset = mFileData[offOffset] | (mFileData[offOffset + 1] << 8); - // can't know the length of the shape ahead of time; will need to check as we go + return GenerateBitmap(shapeOffset); + } + private IVisualization2d GenerateBitmapFromShape(ReadOnlyDictionary parms) { + int offset = Util.GetFromObjDict(parms, P_OFFSET, 0); + if (offset < 0 || offset >= mFileData.Length) { + mAppRef.ReportError("Invalid parameter"); + return null; + } + return GenerateBitmap(offset); + } + + private IVisualization2d GenerateBitmap(int shapeOffset) { + // can't know the length of the shape ahead of time; will need to check as we go int xmin, xmax, ymin, ymax; xmin = ymin = 1000; xmax = ymax = -1000;