diff --git a/applesoft.s b/applesoft.s index 90420c9..ff9fa09 100644 --- a/applesoft.s +++ b/applesoft.s @@ -11,12 +11,21 @@ ; Applesoft ROM entry points and constants ; WG_AMPVECTOR = $03f5 -CHRGET = $00b1 -ERROR = $d412 +CHRGET = $00b1 ; Advances text point and gets character in A +CHRGOT = $00b7 ; Returns character at text pointer in A +SYNCHR = $dec0 ; Validates current character is what's in A +TXTPTR = $00b8 ; (and $b9) ; Current location in BASIC listing +ERROR = $d412 ; Reports error in X +CHKCOM = $debe ; Validates current character is a ',', then gets it +GETBYT = $e6f8 ; Gets an integer at text pointer, stores in X +GETNUM = $e746 ; Gets an 8-bit, stores it X, skips past a comma ERR_UNDEFINEDFUNC = 224 - ERR_SYNTAX = 16 +ERR_TOOLONG = 176 + +MAXCMDLEN = 14 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGInitApplesoft @@ -46,15 +55,16 @@ WGInitApplesoft: WGAmpersand: sta SCRATCH0 SAVE_AXY + SAVE_ZPP ldy #0 ldx SCRATCH0 WGAmpersand_parseLoop: txa - beq WGAmpersand_parseMatchStart ; Check for end-of-statement - cmp #':' - beq WGAmpersand_parseMatchStart + beq WGAmpersand_parseFail ; Check for end-of-statement (CHRGET handles : and EOL) + cmp #'(' + beq WGAmpersand_matchStart sta WGAmpersandCommandBuffer,y @@ -62,25 +72,33 @@ WGAmpersand_parseLoop: tax iny - cpy #14 + cpy #MAXCMDLEN bne WGAmpersand_parseLoop -WGAmpersand_parseMatchStart: +WGAmpersand_parseFail: + ldx #ERR_SYNTAX + jsr ERROR + bra WGAmpersand_done + +WGAmpersand_matchStart: + lda #0 + sta WGAmpersandCommandBuffer,y ; Null terminate the buffer for matching + ldy #0 ldx #0 ; Command buffer now contains our API call phx ; We stash the current command number on the stack -WGAmpersand_parseMatchLoop: +WGAmpersand_matchLoop: lda WGAmpersandCommandBuffer,y - beq WGAmpersand_parseMatchFound ; Made it to the end + beq WGAmpersand_matchFound ; Got one! cmp WGAmpersandCommandTable,x - bne WGAmpersand_parseMatchNext ; Not this one + bne WGAmpersand_matchNext ; Not this one iny inx - bra WGAmpersand_parseMatchLoop + bra WGAmpersand_matchLoop -WGAmpersand_parseMatchNext: +WGAmpersand_matchNext: pla ; Advance index to next commmand in table inc pha @@ -91,12 +109,12 @@ WGAmpersand_parseMatchNext: tax cpx #WGAmpersandCommandTableEnd-WGAmpersandCommandTable - beq WGAmpersand_parseFail ; Hit the end of the table + beq WGAmpersand_matchFail ; Hit the end of the table ldy #0 - bra WGAmpersand_parseMatchLoop + bra WGAmpersand_matchLoop -WGAmpersand_parseMatchFound: +WGAmpersand_matchFound: pla ; This is now the matching command number inc asl @@ -105,26 +123,131 @@ WGAmpersand_parseMatchFound: asl tay lda WGAmpersandCommandTable-2,y ; Prepare an indirect JSR to our command - sta WGAmpersand_commandJSR+1 + sta WGAmpersand_commandJSR+1 ; Self-modifying code! lda WGAmpersandCommandTable-1,y sta WGAmpersand_commandJSR+2 - ; Self modifying code: + ; Self-modifying code! WGAmpersand_commandJSR: jsr WGAmpersand_done ; Address here overwritten with command bra WGAmpersand_done -WGAmpersand_parseFail: +WGAmpersand_matchFail: pla ; We left command number on the stack while matching ldx #ERR_UNDEFINEDFUNC jsr ERROR WGAmpersand_done: + RESTORE_ZPP RESTORE_AXY rts +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGAmpersandIntArguments +; Buffers integer arguments for the current command in PARAMx +; TXTPTR: Start of argument list (after opening parenthesis) +; OUT PARAMx : The arguments +WGAmpersandIntArguments: + SAVE_AXY + + ldy #0 + phy ; Can't rely on Applesoft routines to be register-safe + + lda #'(' + jsr SYNCHR ; Expect opening parenthesis + +WGAmpersandIntArguments_loop: + jsr GETBYT + txa + ply + sta PARAM0,y + phy + + jsr CHRGOT + cmp #')' ; All done! + beq WGAmpersandIntArguments_cleanup + jsr CHKCOM ; Verify parameter separator + + ply + iny + phy + cpy #4 ; Check for too many arguments + bne WGAmpersandIntArguments_loop + +WGAmpersandIntArguments_fail: + ldx #ERR_TOOLONG + jsr ERROR + bra WGAmpersandIntArguments_done + +WGAmpersandIntArguments_cleanup: + jsr CHRGET ; Consume closing parenthesis + +WGAmpersandIntArguments_done: + ply + RESTORE_AXY + rts + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGAmpersandStrArgument +; Buffers a string argument for the current command in PARAM0/1 +; TXTPTR: Start of argument list (after opening parenthesis) +; OUT PARAM0/1 : The argument +WGAmpersandStrArguments: + SAVE_AXY + + ldy #0 + phy ; Can't rely on Applesoft routines to be register-safe + + lda #'(' + jsr SYNCHR ; Expect opening parenthesis + +WGAmpersandStrArguments_loop: + jsr CHRGOT + beq WGAmpersandStrArguments_tooShort + cmp #')' + beq WGAmpersandStrArguments_cleanup + + ply + sta WGAmpersandCommandBuffer,y + iny + phy + cpy #WGAmpersandCommandBufferEnd-WGAmpersandCommandBuffer + beq WGAmpersandStrArguments_tooLong + + jsr CHRGET + bra WGAmpersandStrArguments_loop + +WGAmpersandStrArguments_tooLong: + ldx #ERR_TOOLONG + jsr ERROR + bra WGAmpersandStrArguments_done + +WGAmpersandStrArguments_tooShort: + ldx #ERR_SYNTAX + jsr ERROR + bra WGAmpersandStrArguments_done + +WGAmpersandStrArguments_cleanup: + jsr CHRGET ; Consume closing parenthesis + +WGAmpersandStrArguments_done: + ply ; Null-terminate result + lda #0 + sta WGAmpersandCommandBuffer,y + + lda #WGAmpersandCommandBuffer + sta PARAM1 + + RESTORE_AXY + rts + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Ampersand API entry points @@ -133,14 +256,49 @@ WGAmpersand_done: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; WGAmpersand_view +; WGAmpersand_VIEW ; Create a view ; WGAmpersand_VIEW: + jsr WGAmpersandStrArguments + +; lda WGAmpersandCommandBuffer +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+1 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+2 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+3 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+4 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+5 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+6 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+7 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+8 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+9 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+10 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+11 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+12 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+13 +; jsr PRBYTE +; lda WGAmpersandCommandBuffer+14 +; jsr PRBYTE + + jsr WGCreateView + jsr WGPaintView rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; WGAmpersand_desk +; WGAmpersand_DESK ; Render the desktop ; WGAmpersand_DESK: @@ -155,7 +313,10 @@ WGAmpersand_DESK: ; WGAmpersandCommandBuffer: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +WGAmpersandCommandBufferEnd: +.byte 0 ; Make sure this last byte is always kept as a terminator ; Jump table for ampersand commands. diff --git a/guidemo b/guidemo new file mode 100644 index 0000000..076a4aa Binary files /dev/null and b/guidemo differ diff --git a/guidemo.dsk b/guidemo.dsk index 36f93eb..a1218e2 100644 Binary files a/guidemo.dsk and b/guidemo.dsk differ diff --git a/guidemo.o b/guidemo.o new file mode 100644 index 0000000..0107320 Binary files /dev/null and b/guidemo.o differ diff --git a/views.s b/views.s index be78438..02e0a29 100644 --- a/views.s +++ b/views.s @@ -26,7 +26,7 @@ WGCreateView: SAVE_AXY SAVE_ZPS - + ldy #0 jsr scanHex8 pha