First you have to use _FindSym
to locate the file. _FindSym
's
output puts an ABS pointer in bde
. All the routines we'll
be using to access this will use ahl
so we need to do
two commands to put bde
into ahl
ex de,hl ld a,b
This can be further simplified by using
_Ex_ahl_bde
=$45f3. This is
one byte longer since it is a call
but will still retain a
instead of writing b
over it.
I hate trying to assemble someone else's code and getting all these error messages dealing with the include files. That is why I've pasted the equates for many of the ROM Calls used at the top of the routine. Their addresses are also pasted in the comments.
Since there's no step by step process to learn this section which I can lay out for you, I'm just going to go through some examples. You can do anything with TI-OS variables, so adapt these routines to what you want to do.
Stupid Strings
Let's make a routine called
StupStr.asm
which will create a string and store a sentence
to it.
#include "ti86asm.inc" ;normal include file ; with common ROM calls _Ex_ahl_bde =$45f3 ;like 'ex bde,ahl' _ahl_Plus_2_Pg3 =$4c3f ;ahl=ahl+2 _Set_ABS_Dest_Addr =$5285 _Set_ABS_Src_Addr =$4647 _Set_MM_Num_Bytes =$464f _MM_Ldir =$52ed .org _asm_exec_ram ld hl,string-1 ;copy anything before string ; for type byte rst 20h ;call _Mov10toOP1 rst 10h ;call _FindSym to see if ; variable exists call nc,_delvar ;delete variable if it exists ;all necessary info still ; preserved ld hl,end-start ;minus start from end of string ; so result is length of string call _CreateSTRNG ;$472f create string call _ex_ahl_bde ;$45f3 ABS bde & ahl swapped call _AHL_Plus_2_Pg3 ;$4c3f increase ABS ahl by two call _Set_ABS_Dest_Addr ;$5285 set that as ; destination for block copy sub a ;AKA ld a,0 ld hl,start ;hl points to string_start ;address of string is in ; relation to 16 bit ; and ram page call _Set_ABS_Src_Addr ;$4647 set that as source ; for block copy sub a ;AKA ld a,0 -it's on already ; swapped in page (0) ld hl,end-start ;length of string call _Set_MM_Num_Bytes ;$464f set # of bytes to copy ; in block copy jp _MM_Ldir ;$52ed ABS block copy ;we jump instead of calling ; and returning ;this way we just use ; _MM_Ldir's ret as ours ;saves 1 byte string: .db 6,"Stupid" ;length indexed string name start: .db "This is a stupid string." end: .end
This routine creates a String named "Stupid" and puts "This is a stupid string" as its data.
hl
and create it.
bde
(what
_CreateSTRNG returned) into ahl
.
a
with zero because our string is in the
64k of bytes currently
available. We can access it with a 16 bit pointer because it
is on a page that is swapped in (all asm programs are put
into an area on RAM page 0 which is always
swapped in).
High Scores
Uh, Oh! TI-OS doesn't save your high scores. You need to copy them to the
program as explained in the game saved
variables section.
A major thing to remember when you're creating programs is that the first byte of the data (after the two bytes for the length of the program) there is a byte telling whether the program has been tokenized or not. It will be $00 if it is untokenized, or $33 if it has been tokenized.
_asapvar =$d6fc ;name of the currently ; running program (this ; one!) _set_abs_src_addr =$4647 _set_abs_dest_addr =$5285 _set_mm_num_bytes =$464f _mm_ldir =$52ed . . . . . . save_game: ld hl,_asapvar ;name of current ; program running rst 20h ;copy to OP1 rst 10h ;_findsym ld a,b ;returns bde as prog data ld hl,data_start-_asm_exec_ram+2+2 ;offset in this program ; for start ; of saved game data ;2 bytes for prog length ;2 bytes for asm ; identifier bytes add hl,de ;hl=pointer to data in ; original prog adc a,$00 ;in case we overlapped pages ;if carry was set in previous ; instruction...this will ; add 1 to a else...it ; adds 0 to a call _Load_RAM_ahl ;$462f - convert ahl to a ; RAM page and 16 bit pointer ld a,(high_score) ;get high_score from ; this program ld (hl),a ;store it into the ; actual program's ; data ret . . . . . . high_score: .db 0 ;high score in game
What we did was:
_asm_exec_ram
on execution).
_asm_exec_ram
into the accumulator
(a
) and then put that into the high score of the
program on the swapped
in RAM page.
Suppose you wanted to not just copy one byte, but several. Here's an example of copying several bytes of program data back to the original program in memory. It's the Write Back routine discussed in the Intermediate Variables Section.
_asapvar =$d6fc _set_abs_src_addr =$4647 _set_abs_dest_addr =$5285 _set_mm_num_bytes =$464f _mm_ldir =$52ed save_game: ld hl,_asapvar ;name of current ; program running rst 20h ;copy to OP1 rst 10h ;_findsym ld a,b ;returns bde as prog data ld hl,data_start-_asm_exec_ram+2+2 ;offset in this program ; for start ; of saved game data ;2 bytes for prog length ;2 bytes for asm ; identifier bytes add hl,de ;hl=pointer to data ; in original prog adc a,$00 ;in case we overlapped ; pages if carry was set ; in previous ; instruction...this ; will add 1 to a ; else...it adds 0 to a call _set_abs_dest_addr ;set that as the absolute ; destination address ; to copy to sub a ;no absolute addressing now ld hl,data_start ;*get data from here call _set_abs_src_addr ;set that as the absolute ; source address to copy ; from ld hl,data_end-data_start ;*number of bytes to save call _set_mm_num_bytes ;set that as the number ; of bytes to copy jp _mm_ldir ;perform absolute address ; data block copy data_start: ;start of data to copy high_score: .db 0 ;high score high_score_initials: .db "AAA",0 ;initials of high score ; holder data_end:
Lists
Now, let's make a list named "Stupid" with
2 elements in it. You can download the
program StupLst.
#include "ti86asm.inc" ;normal include file with ; common ROM calls _Ex_ahl_bde =$45f3 ;like 'ex bde,ahl' _ahl_Plus_2_Pg3 =$4c3f ;ahl=ahl+2 _Set_ABS_Dest_Addr =$5285 _Set_ABS_Src_Addr =$4647 _Set_MM_Num_Bytes =$464f _MM_Ldir =$52ed .org _asm_exec_ram ld hl,list-1 ;copy anything before ; list for type byte rst 20h ;call _Mov10toOP1 rst 10h ;call _FindSym to see if ; variable exists call nc,_delvar ;delete variable if it ; exists all necessary ; info still preserved ld hl,2 ;2 elements call _CreateRLIST ;create real list (as ; opposed to complex) call _ex_ahl_bde ;$45f3 ABS bde & ahl ; swapped call _ahl_Plus_2_Pg3 ;get paste element # byte call _Set_ABS_Dest_Addr ;$5285 set that as ; destination for ; block copy sub a ;AKA ld a,0 ld hl,start ;hl points to list_start ;address of list is ; in relation to 16 bit ; and ram page call _Set_ABS_Src_Addr ;$4647 set that as ; source for block copy sub a ;AKA ld a,0 -it's on ; already swapped in ; page (0) ld hl,end-start ;length of list call _Set_MM_Num_Bytes ;$464f set # of bytes ; to copy in block copy jp _MM_Ldir ;$52ed ABS block copy ;we jump instead of ; calling and returning ;this way we just use ; _MM_Ldir's ret as ours ;saves 1 byte list: .db 6,"Stupid" ;length indexed list name start: .db $00,$00, $fc, $10, $00, $00, $00, $00, $00, $00 .db $00,$00, $fc, $20, $00, $00, $00, $00, $00, $00 end: .end
Matrices
Check out how to make matrices in
StupMat.
#include "ti86asm.inc" ;normal include file ; with common ROM calls _Ex_ahl_bde =$45f3 ;like 'ex bde,ahl' _ahl_Plus_2_Pg3 =$4c3f ;ahl=ahl+2 _Set_ABS_Dest_Addr =$5285 _Set_ABS_Src_Addr =$4647 _Set_MM_Num_Bytes =$464f _MM_Ldir =$52ed .org _asm_exec_ram ld hl,matrix-1 ;copy anything before ; matrix for type byte rst 20h ;call _Mov10toOP1 rst 10h ;call _FindSym to see ; if variable exists call nc,_delvar ;delete variable if it ; exists ;all necessary info ; still preserved ld hl,1*256+2 ;1 row, 2 columns call _CreateRMAT ;create real matrix ; (as opposed to complex) call _ex_ahl_bde ;$45f3 ABS bde & ahl ; swapped call _ahl_Plus_2_Pg3 ;get paste row byte ; and col byte call _Set_ABS_Dest_Addr ;$5285 set that as ; destination for ; block copy sub a ;AKA ld a,0 ld hl,start ;hl points to matrix_start ;address of matrix is ; in relation to 16 bit ; and ram page call _Set_ABS_Src_Addr ;$4647 set that as ; source for block copy sub a ;AKA ld a,0 -it's on ; already swapped ; in page (0) ld hl,end-start ;length of matrix call _Set_MM_Num_Bytes ;$464f set # of bytes ; to copy in block copy jp _MM_Ldir ;$52ed ABS block copy ;we jump instead of ; calling and returning ;this way we just use ; _MM_Ldir's ret as ours ;saves 1 byte matrix: .db 6,"Stupid" ;length indexed matrix name start: .db $00,$00, $fc, $10, $00, $00, $00, $00, $00, $00 .db $00,$00, $fc, $20, $00, $00, $00, $00, $00, $00 end: .end
Remember that if you want to make a complex type
of the above variables, create the complex
form of the variable with double the size. You're
going to have to put put the real
part with the complex part following. Here's the
data for a complex list with two elements.
More information on real and complex numbers
can be found in the Binary Coded
Decimal Section.
Every Variable
I hope that's all the examples you need. If you
didn't catch it above, you can download
all the source files for these routines:
complex_list:
start:
;element 1 = (1,1)
.db $01, $00, $fc, $10, $00, $00, $00, $00, $00, $00
.db $01, $00, $fc, $10, $00, $00, $00, $00, $00, $00
;element 2 = (2,2)
.db $01, $00, $fc, $20, $00, $00, $00, $00, $00, $00
.db $01, $00, $fc, $20, $00, $00, $00, $00, $00, $00
end: