Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Some experiments in somewhat uncharted territories

196 views
Skip to first unread message

Benoit0123

unread,
Mar 6, 2015, 3:31:58 AM3/6/15
to
How to call Applesoft subroutines from assembly language subroutines
How to define Applesoft procedural functions and call them from Applesoft
I hereby take for granted that every reader of this article knows how to
call assembly language routines from Applesoft programs (this has been
described in numerous reference manuals, articles and books, cf. keywords
USR, CALL and & in such literature), or at least has heard about that
feature.
Hereby I propose a mechanism leading to the Applesoft side of an application
being called upon by the machine code side of this application (that is the
reverse path of the previous one and much, much less common AFAIK), thus by
using what I'm naming "Ex nihilo GOSUB stack frames" in this document.
"Ex Nihilo GOSUB stack frames" have been around (at least in my mind) since
I implemented co-routines as part of an Applesoft extension utility some
months/years ago.
Every subsequent version of this utility (name is Peersoft) has found a
creative use of this small hack, the most recent use being the support for
hardware interrupt servicing (mouse card based for the time being) by
Applesoft subroutines (to be released by the end of this week or next).
In this way,
actual mixed arithmetic (i.e. with both integer and FP) can be performed ;
assembly language routines can be customized using scripts of an
interpretive language like BASIC and easily tailored to specific contexts
on the field and without any reassembly or recompile.
Well, this article is to be considered as a demo of the potential of such
mechanism: I'll show how to call Applesoft subroutines from assembly
language programs, themselves could have been called from within an
Applesoft application programs (we'll stop here the "russian puppets"
game). Two mechanisms are illustrated here:
simple generic call from assembly to Applesoft and return;
Procedural functions (or PF for short): call from assembly as part of the
processing of a function definition written in Applesoft. In the codlet
above, line 20 tells that for every function call:
The actual argument value (at time of call) will be passed in the N named FP
variable;
The returned result will be extracted from the S FP variable value
The function body begins at line 2000. The unusual aspect is that it is
Applesoft code and not ML despite the fact that, from an end user/programmer
point of view, the interface be identical to a ML user defined function.
One thing that is missing from the provided code here is the backup of the
original value of variables N and S here and adhoc restore operation
afterward. By the way the N and S variables could be either integer or FP
but not of string type.
1 PRINT CHR$(4)”MAXFIELS 1”: HIMEM: 38400:BA = 38400: PRINT CHR$
(4)”BLOAD JAH2.0”
9 REM EARLY TESTS
10 CALL BA,1000:N = 4: CALL BA,2000: PRINT S
19 REM PF PREPARATION STEP
20 CALL BA + 3,N,S,2000: POKE 10,76: POKE 11,6: POKE 12,150
29 REM PF EXECUTE STEP
30 FOR J = 1 TO 8: PRINT J” ” USR (J): NEXT: END
1000 PRINT “HELLO”: RETURN
1997 REM THE LINE BELOW IS THE
1998 REM BODY OF THE PROCEDRAL
1999 REM FUNCTION S=F(N)
2000 S = 0: FOR I = 0 TO N:S = S + I : NEXT : RETURN
]RUN
HELLO
10
1 1
2 3
3 6
4 10
5 15
6 21
7 28
8 36
And now the Assembly code source file content. For the folks who are too
lazy to type in the source code and assemble it, I'll put a disk image on my
Web site in the days to come and advise within this thread once uploaded.
* 22àAnnières (for french speaking countries) or
* JAH (just a hack) (for the rest of the world)
* just get a look @ https://www.youtube.com/watch?v=nkSYLi2N9zs
* to get the point.. (french language understanding required).

* Usage: CALL 38400,1000: REM will call Applesoft subroutine at line 1000
* from assembly
 and return.
* CALL 38403,<argVName>,<resVName>,<BodyStartLine#> for the PF prepare
* and PRINT USR (<expression>) for the PF execute.
* for more elaborate usage (procedural functions)

* Published under the Creative commons license

* Benoit Gilon
* Merlin assembler
TOKGOSUB = $B0

* Page zero equates

REMSTK EQU $F8

TXTPTR EQU $B8

OLDTEXT EQU $79
TRCFLG EQU $F2
CURLIN EQU $75
LOWTR EQU $9B
VALTYP EQU $11
FORPNT EQU $85
ARYTAB EQU $6B
VARPNT EQU $83
* Some helpful ROM routines from Applesoft
NEWSTT EQU $D7D2
PTRGET EQU $DFE3
CHKCOM EQU $DEBE
LINGET EQU $DA0C
FNDLIN EQU $D61A
UNDERR EQU $D97C
CHKNUM EQU $DD6A
MOVMF EQU $EB2B
MOVFM EQU $EAF9
UNDERR EQU $D97C
TMERR EQU $DD76
MOVFM EQU $EAF9
GIVAYF EQU $E2F2
LET2 EQU $DA63

DO 0
STD MAC
LDA ]1
STA ]2
LDA ]1+1
STA ]2+1
<<<
FIN

XC ;Enable 65C02 opcodes

 ORG $9600

CLC
BCC GENFEAT Always
JMP PREPARE
* Here the entry point for procedural functions
FUNC JSR CHKNUM
STD ARVPTR;FORPNT
BIT ARINTYP bit N set iif integer var.
JSR LET2
STD LINPTR;LOWTR
SEC ;Flag that we come from procedural functions
GENFEAT ROR FMODE
BMI :0 COMMON1 already called as part of the PREPARE step
JSR COMMON1
0 LDY #8-1

]LOOP LDX SVOFST,Y

 LDA 0,X

 STA SVAREA,Y

 DEY

BPL ]LOOP

STZ TRCFLG
TSX

STX SAVSTP

* This is the critical code segment

LDA #>RETOUR-1

 PHA

LDA #RETOUR-1

 PHA

LDA TXTPTR+1

 PHA

 LDA TXTPTR

 PHA

LDA CURLIN+1

PHA

 LDA CURLIN

 PHA

LDA #TOKGOSUB

 PHA

* Let (TXTPTR) set to (LOWTR) minus 1

 LDX LOWTR+1

 LDY LOWTR

 BNE :0

DEX

:0 DEY

STX TXTPTR+1

STY TXTPTR

JMP NEWSTT

* Procedural functions: prepare step
PREPARE LDA #0 Handle arg variable
JSR COMMON2
LDA #3 Handle Result variable
JSR COMMON2
JSR COMMON1 Handle PF start line #
STD LOWTR;LINPTR

RETOUR LDY #8-1

]LOOP LDX SVOFST,Y

 LDA SVAREA,Y

STA 0,X

 DEY

BPL ]LOOP

BIT FMODE
BMI :0
LDA #RESVPTR
LDY #>RESVPTR
JMP MOVFM
:0 RTS


COMMON1 JSR CHKCOM

JSR LINGET

JSR FNDLIN

 BCS :0

 JMP UNDERR

:0 RTS

COMMON2 PHA
JSR CHKCOM
JSR PTRGET
BIT VALTYP
BPL :1
]ERR JMP TMERR
:1 CMP ARYTAB
TYA
SBC ARYTAB+1
BCS ]ERR
PLX
TYA
STA SVVAR+2,X
LDA VARPNT
STA SVVAR+1,X
LDA VALTYP+1
STA SVVAR+0,X
RTS
SVVAR EQU *
ARINTYP DS 1
ARVPTR DS 2
RSINTYP DS 1
RSVPTR DS 2

FMODE DS 1
RESVPTR DS 2

SAVSTP DS 1

LINPTR DS 2
SVAREA DS 8

SVOFST DFB REMSTK, TRCFLG

 DFB TXTPTR, TXTPTR+1

DFB CURLIN, CURLIN+1

 DFB OLDTEXT, OLDTEXT+1


END
In the same vein, why not think about a similar hack for calling Integer
BASIC routines from Applesoft?.. Humm.. that will extend the 2015 todo list
by 1 item...
In the meantime I wish all an happy PI day (I'll be not late on this one at
least).

Benoît

--
Growing old is mandatory..
growing up is optional..
But the other way round is as true.

Benoit0123

unread,
Mar 6, 2015, 7:14:18 AM3/6/15
to
Oops
I based my previous message compositing upon a non final version of the
assembly listing. One should read for the "RETOUR" subroutine:

RETOUR LDY #8-1

]LOOP LDX SVOFST,Y

 LDA SVAREA,Y

STA 0,X

 DEY

BPL ]LOOP

BIT FMODE
BMI :0
LDA RESVPTR instead of #RESVPTR
LDY RESVPTR+1 instead of #>RESVPTR
JMP MOVFM
:0 RTS

The disk image will be uploaded on tommorrow morning (localtime) the URL to
download will be:
http://bgilon.free.fr/apple2/JAH2.0.zip
It will contain a disk image (.do suffix for DOS 3.3 order).

Benoit0123

unread,
Mar 10, 2015, 12:15:58 PM3/10/15
to
During the last week end, I made some improvements to JAH.
The updated version now allows to select as part of the
"Procedural Function" prepare step, a mode in order to cater
with a completely private memory area (for simple, array and string
storage).
Hence the requirement to backup and restore values of those variables from
the main program flow is gone.
Select this mode (MO% value set to 128) when:
a) you do not require a globally set variable/array within the body of the
PF:
b) you can manage to store all your variable storage needs within 512 bytes.
Howecer this size limit can be increased by reasssembling the ML portion of
the demo.
Select the classic mode (i.e. MO% value set to 0) otherwise.
Here is the Applesoft part of the demo (edit line 2 and variable MO% setting
at its bedinning) in order to switch between modes.

0 REM INIT THE ENVIRONMENT
1 PRINT CHR$ (4)"MAXFILES 1": HIMEM: 37888: PRINT CHR$ (4)"BLOAD
JAH2.0.2"
2 MO% = 128: ON MO% = 128 GOTO 3: CLEAR :S = 0:I = 0:N% = 0:S0 = 0:N0% =
0:MO% = 0
3 BA = 37888
9 REM EARLY TESTS
10 CALL BA,1000
12 REM N% = 4: CALL BA,2000: PRINT S
19 REM PREPARE STEP
20 CALL BA + 3,MO%,N%,S,2000: POKE 10,76: POKE 11,6: POKE 12,148
21 REM EXECUTE STEP
22 FOR J = 1 TO 8: PRINT J" " USR (J): NEXT : END
1000 PRINT "HELLO": RETURN
1995 REM THE 3 LINES BELOW ARE
1996 REM THE BODY OF THE P.F.
1997 REM S=FUNCTION(N)
1998 REM SUM(I), I FROM 0 TO N
1999 REM CACHE WITH N0%,S0
2000 ON SGN (N%-N0%) + 2 GOTO 2001,2002:S = S0: FOR I = N0% + 1 TO N%:S =
S + I: NEXT :N0% = N%:S0 = S: RETURN
2001 S = 0: FOR I = 1 TO N%:S = S + I: NEXT :N0% = N%:S0 = S: RETURN
2002 S = S0: RETURN

URL for donloading the disk image (along with the source code) is
http://bgilon.free.fr/apple2/JAH2.0.2.zip
This is a working copy of Merlin 8 DOS 3.3, the source file is named:
JAH2.0.2.s

Any feedback would be welcome.

D Finnigan

unread,
Mar 20, 2015, 5:13:29 PM3/20/15
to
Benoit0123 wrote:
>
> Any feedback would be welcome.
> Benoît
>

Hi, I downloaded your source last week and looked at it. Can you send me
some more documentation on how your code works and what it is useful for?
Either French or English is fine with me.

--
]DF$
Apple II Book: http://macgui.com/newa2guide/
Usenet: http://macgui.com/usenet/ <-- get posts by email!
Apple II Web & Blog hosting: http://a2hq.com/

Benoit0123

unread,
Mar 22, 2015, 5:20:05 PM3/22/15
to
D Finnigan wrote:
> Benoit0123 wrote:
>>
>> Any feedback would be welcome.
>> Benoît
>>
>
> Hi, I downloaded your source last week and looked at it. Can you send me
> some more documentation on how your code works and what it is useful for?
> Either French or English is fine with me.
>
pm sent to David.
BTW I plan to integrate the PF mechanism in a future version of Peersoft.

Benoit0123

unread,
Mar 31, 2015, 6:04:46 PM3/31/15
to
JAH 2.1 has been posted on my web site, for those interested.
The URL to download is http://bgilon.free.fr/apple2/JAH2.1.zip
Briefly stated it provides the features below in addition to those offered
by v2.0.2.
The included JAHELLO Applesoft program is a sample progarm for you to get
the idea.
The source file on teh disk image is JAH2.1.s (Merlin format).
New bits meaninful for specifying operation mode:
. b1 for specifying an Applesoft subroutine (by its begin line #) to
initialize variables objects required by the computation itself. Helpful
when a DEF FN function is required or to initialize constants variables or
arrays, particularly when b7 is itself set (meaning that the computation
should be handled with a completely separate data segment).
. b0 for specifying a list of variables that should reside on top of SVM
(simple variables memory segment, thus speeding references to those
variables from the program flow). This is an imported mechanism from
Peersoft.
. b7 (introduced in JAH2.0.2) for dealing with a private data segment
enforced for every USR subsequent call handling (size is preset to 512 bytes
but can be tailored to one's own requiredment by just reassmbling the source
file).

This is the JAH final release as a standalone UPO (unidentified programmmed
object ;-).

Peeersoft next update (due to be released before August this year) will
include the PF (Procedural functions) feature.
0 new messages