Erico Patricio Monteiro's BASIC Adventure Game graphics

Got a software project you're working on? Share the details with us here.
Please only post 1 topic per project and keep the replies and threads pertaining to the project within the same post.
Forum rules
Software Project Forum Group:
Please 1 one topic per project.
Keep all comments and replies and threads within the same topic, and try to avoid creating new ones.

Erico Patricio Monteiro's BASIC Adventure Game graphics

Postby nowhereman999 » Sun Dec 17, 2017 8:29 pm

Hi Erico,

For fun I wrote up a little code to teach myself how to transfer variables from BASIC to an ML program. Your question on Facebook about storing semi graphic pictures for use in your BASIC adventure game gave me a good excuse to give it a try.
See below for the Assembly code and I've attached the .asm and .BIN file ready to test with your own BASIC program. All you need to do is get the pictures into RAM at address $E00,$E00+320,$E00+320*2,$E00+320*3,...
Then use the BASIC commands:
Code: Select all
* 10 LOADM"SHOWPIC" :' The assembled version of this program
* 20 DEF USR0(&H1DA)
* 30 A=USR0(4):' This will show picture 4
* 40 B=10
* 50 A=USR0(B):' This will show picture 10, only room for 100 pictures in upper 32k of RAM

If you are happy with it, we can write up a loader program that will put your screen pictures up in the high 32k RAM for a 64k CoCo. Then tweak the program to use $8000 + for the pictures
If you don't want to go this route, no problem. As I said I wrote this up for my own understanding...
Cheers,
Glen

Here's the code:
Code: Select all
* Called from a USRx(y) routine in BASIC
* setup with DEF USRx(&H1DA)
* Called with A=USRx(y)
* where x is the number 0 to 9 and y is an integer or variable with a value from 0 to 65535
* For this routine y should not be bigger then 100
* For more help look at the bottom of this file
*
* 10 LOADM"SHOWPIC" :' The assembled version of this program
* 20 DEF USR0(&H1DA)
* 30 A=USR0(4):' This will show picture 4
* 40 B=10
* 50 A=USR0(B):' This will show picture 10, only room for 100 pictures in upper 32k of RAM
* ...
*********************************************************

        ORG     $1DA        * Exists in the cassette Buffer (Not cassette comaptible code)
INTCNV  EQU     $B3ED       * CONVERT FPA0 TO A SIGNED TWO BYTE INTEGER; RETURN VALUE IN ACCD
START
        JSR     INTCNV      * CONVERT FPA0 TO A SIGNED TWO BYTE INTEGER; RETURN VALUE IN ACCD
        STB     Number+1    * Save the User number (Self modify) the LDB command below
        LDA     #255        * 320 = 255 + 65 below
        MUL
        STD     Adder+1     * Save the first result (self modify) in the ADDD instruction below
        LDA     #65
Number:
        LDB     #$00
        MUL
Adder:
        ADDD    #$0000      * D now = 320 * User number
        ANDCC   #$50        * Turn off the Interrupts
        CLR     $FFDF       * Go To RAM mode to load our previously saved
        STU     RestoreU+1  * Save U so we can restore it before exiting back to BASIC
        LDU     #$E00       * Change this to $8000 when the images are stored in upper RAM
        LEAU    D,U
        LDX     #$400
!       LDD     ,U++
        STD     ,X++
        CMPX    #$400+320   * Check for end of image
        BNE     <
RestoreU:
        LDU     #$0000
        CLR     $FFDE       * Back to ROM mode before returnning to BASIC
        RTS                 * BASIC will restore D,X,CC everything else you must save and restore yourself
        END     START


From Extended Color Basic Manual:
Passing Values to an ML Subroutine
USING THE INTCNV ROUTINE
If you want to pass an integer 10 your ML subroutine, use the integer as
the "argument" in your USR function. For example:
A=USR1(5)
calls Machine Code Program 1 and passes the argument 5 to it. You
can then call the INTCNV routine, which gets the integer and stores it
in Register D.

USING THE VARPTR FUNCTION
Another way to pass an argument to your ML Subroutine is to pass a
"pointer" to the address where a variable's value is stored. You can do
this with the VARPTR function:
VARPTR variable returns a pointer to wllere the variable's value is
stored
For example:
A=USRlIVARPTRIB»
calls Ml Subroutine 1 and passes a pointer to Variable B's address. The
pointer is stored in Register X. Your ML subroutine needs to know
whether the variable is string or numeric.
Byte 1
Byte 2 ;
Byte 3
Byte 4 ;
Byte 5
If lhe variable is string, your Ml subroutine can find the string's 5-byte
descriptor in Register X. This descriptor tells where the string is:
Byte 1 = the length of the siring lin characters/
Byte 2 = reserved for the compuler'~ use
Bytes 3 ,md 4 = address of the fihl byte in the siring
Byte 5 = reserved for the coml>Uler's use
If Ihe variable is numeric. your program can find Ihe dddress of the
number's floating point value in Register X. This floating point value has
this format:
lhe exponent of Ihe mantissa
Ihe mantissa's most significant byte IMSBI
the mantiss<l's next MSB
the mantiSSil's next MSB
the mantissa's least significant byte (lSBl
The exponent is a signed 8-bit integer with 128 decimals added to it.
An exponent of 0 means lhe number is O. in which c<lse the mantissa is
insignificant. The exponent's most signific<lnt bit stores the exponent's
sign: 0 if positive, 1 if negative.
The mantissa is stored in normalized form with the most significant bit
of the mantissa's MSB assumed to be ,. This bit can indicate the mantissa's
sign: 0 if positive, 1 if negative.
You may wanl to use VARPTR to pass an array variable's pointer 10 an
Ml subroutine. For example:
A=USRl<VARPTR<B(Sl l
calls Ml Subroutine 1 and passes a pointer to Array B's Element 5.
Your Ml subroutine can find the elements' values in memory as follows
(from low to high memory):
Value of first element of last dimension
Value of last element of lasl dimension
Value of first element of first dimension
Value of last element of first dimension
Each element is five bytes long.
Returning Values to BASIC
USR always returns at least one value to BASIC. This value is the argument
you originally pass to the Ml subroutine, unless your Ml subroutine
changes or modifies it. as described below.
USING GIVABF TO RETURN AN INTEGER
To return a specified integer to BASIC. you can have your Ml subroutine
load the integer into Register D and call GIVABF, as demonstrated
earlier.

MODIFYING BASIC VARIABLES
You can return any specified value to BASIC by having your Ml subroutine
modify a BASIC variable's value, For example, assume you call an
Ml subroutine with this statement:
201
202
A$=(USR1CVARPTR(5$»
You can have your ML subroutine modify B$'s value and then end the
routine with an RT$ instruction. This causes U$R to return with 8$'s
modified value.
If your ML subroutine modifies a string variable, be careful of the
following:
Although you can change a string descriptor's length byte to
"shorten" a string, you cannol "lengthen" a string. If you
don't know what size string your ML subroutine will return,
reserve 255 bytes (the maximum size) for the string's value
before passing il to the ML subroutine. For example:
5$=STRING$(255)
A$ = USR0 (VARPTR (B$»
passes a pointer to a 255-character string of blank spaces to
the USR function. The ML subroutine can then put a string
of up to 255 characters into the memory pointed to by B$ or,
if necessary, shorten the string's length byte.
You can modify the starling address of a string by changing
the 2-byte pointer in the string descriptor. When you do this,
though, we recommend the new starting address be an address
included in the original string.
You can swap the starting addresses of two strings. This may
be useful for sorting strings. If you do this, though, be careful
not 10 "intersect" two strings.
If your ML subroutine modifies a variable that already points
to a string literal, this will change your BASIC program. For
example, assume you have this statement in your BASIC
program:
5$ = "ABC"
If your ML subroutine modifies B$, your BASIC program is
changed. To avoid this problem, add a null string ("") to any
string literal that your ML subroutine will modify. For
example:
B$ = "ABC" + ""
The null string forces BASIC to copy the string into string
space, where your ML subroutine can safely modify it.

Using Stack Space
An ML subroutine, called by USR, that requires more than 30 bytes of
stack storage must provide its own stack area. Save BASIC's stack
pointer upon entry to the USR function, setting up a new stack pointer
and restoring BASIC's stack pointer prior to returning to BASIC. The values
of the A, B, X, and CC registers need not be preserved by USR.
Attachments
SHOWPIC.BIN.zip
Program to show 320 byte semi graphic picture onto the text screen. Used from BASIC
(682 Bytes) Downloaded 87 times
nowhereman999
 
Posts: 33
Joined: Mon Sep 18, 2017 11:43 pm

Return to Software Projects

Who is online

Users browsing this forum: No registered users and 2 guests

cron