Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

The long name exception is probably with the DEF statement because that entry has to go into the REF/DEF table in 99/4A RAM, as well as being read by the E/A or XB loader.

 

Try something more like this and see if it compiles:

 

       DEF MAIN

MAIN   CLR  R1
long_loop_name DEC R1
               JNE long_loop_name
       END
Edited by matthew180
Link to comment
Share on other sites

There is a difference between internal labels and external labels. If you use a DEF, the label will be put into the object code so that the linking loader can resolve REFs with it. If it does not appear in a DEF or REF, the symbol length is just a matter of the assembler.

 

[Edit: I was too slow... ]

Edited by mizapf
Link to comment
Share on other sites

Your example worked for me unmodified.

 

* Loaded into Asm994a v3.010

* Checked "Def Regs", "Produce Listing File", and "Produce HEX Obj File"

* Copied resulting .obj file to my DSK3 directory for Classic99

* Run Classic99 with E/A cart

* Choose #3 in main E/A menu

* DSK3.long_label_test.obj

* Press enter

* START

Link to comment
Share on other sites

 

Same question, Walid: Are you using Asm994a v3.010?

 

...lee

Yes I am.

 

So here's a weird one for you: it seems that if the object file is saved with the .obj extension, it will run just fine. However, if the object file has the _o or .o extension, then I get the ILLEGAL TAG error...

I'm used to name my object files xxxx_o and never had that issue before. Go ahead and try it and please let me know if I am going crazy here... My Classic99 version on this computer is QI371.

Link to comment
Share on other sites

Yes I am.

 

So here's a weird one for you: it seems that if the object file is saved with the .obj extension, it will run just fine. However, if the object file has the _o or .o extension, then I get the ILLEGAL TAG error...

I'm used to name my object files xxxx_o and never had that issue before. Go ahead and try it and please let me know if I am going crazy here... My Classic99 version on this computer is QI371.

 

I'm using QI372; but, now that you mention it, I seem to remember having some similar kind of problem running in FIAD mode. I'm sorry that I don't remember the specifics—but, I think that's what drove me to have Asm994a copy my object files to a disk image from which I copied to a FIAD directory with Fred's Ti99Dir. A RPITA, but it works.

 

...lee

Link to comment
Share on other sites

Yes I am.

 

So here's a weird one for you: it seems that if the object file is saved with the .obj extension, it will run just fine. However, if the object file has the _o or .o extension, then I get the ILLEGAL TAG error...

I'm used to name my object files xxxx_o and never had that issue before. Go ahead and try it and please let me know if I am going crazy here... My Classic99 version on this computer is QI371.

 

It's because Classic99 is not translating the file. (Unfortunately the 'ILLEGAL TAG' message given by the loader isn't very useful).

 

In order to read /Windows text files/ as TI files, Classic99 resorts to the extension. If the extension is .TXT or .OBJ (and .OBJ is only there to support Asm994A), then it knows it's a text file and applies the translation.

 

Troubleshooting this would have been easy the same way you would have on the original machine -- load the file into the editor and view it - you would have seen it was all corrupted. :) Alternately, look at the debug log and see what Classic99 was trying to do. :)

 

By default, files without a Windows extension are treated as DF128 (to match the TIFILES behaviour) - there is an option on the disk config to treat them as text files, which would fix your _o "extension". The only way to make ".o" read as a Windows text file in Classic99 is to apply the file type override: DSK1.?W.FILE.O (?W - read as Windows Text). The log will always tell you what it tried to open.

Link to comment
Share on other sites

  • 2 months later...

Is there an easier way to extract the MSB and LSB of an address in WinAsm99/Asm994a than this (example from a repeating sound list)?

SNDLST BYTE ...
       ...
       BYTE 0
       BYTE SNDLST/256,-SNDLST/256*256+SNDLST
       BYTE -1

Note that you cannot simply use:

       DATA SNDLST

because this will be adjusted to an even address.

Link to comment
Share on other sites

Is there an easier way to extract the MSB and LSB of an address in WinAsm99/Asm994a than this (example from a repeating sound list)?

SNDLST BYTE ...
       ...
       BYTE 0
       BYTE SNDLST/256,-SNDLST/256*256+SNDLST
       BYTE -1

Note that you cannot simply use:

       DATA SNDLST

because this will be adjusted to an even address.

 

I ran into this problem when I was creating sound lists for my CRPG, the even/odd address issue. I fixed it by using base address and labels for each sound effect in a pure byte list, and created a data-address table at the start to store the exact location of each sound.

 

Repeating sounds, though, I still had to calculate a literal address... there just isn't another way to do that cleanly with labels.

 

Adamantyr

Link to comment
Share on other sites

Is there an easier way to extract the MSB and LSB of an address in WinAsm99/Asm994a than this (example from a repeating sound list)?

SNDLST BYTE ...
       ...
       BYTE 0
       BYTE SNDLST/256,-SNDLST/256*256+SNDLST
       BYTE -1
Note that you cannot simply use:
       DATA SNDLST
because this will be adjusted to an even address.

 

Can you elaborate on what your meaning is. Looks like your trying to save a byte?

Link to comment
Share on other sites

Can you elaborate on what your meaning is. Looks like your trying to save a byte?

 

No, I'm, trying to create a sound list that can be relocated, without counting bytes in order to make sure that the loop address is located at an even address, which it would have to be if you used a DATA directive. If you use a DATA directive and the address is not even, WinAsm99 inserts a zero byte before the loop address, which breaks the sound list. Anyway, my method for calculating the MSB and LSB in this parenthesis free expression language works, but WinAsm99 has several undocumented features (e.g conditional assembly, longer labels) so it might have a secret way of getting the MSB and LSB of a labelled address.

Link to comment
Share on other sites

 

No, I'm, trying to create a sound list that can be relocated, without counting bytes in order to make sure that the loop address is located at an even address, which it would have to be if you used a DATA directive. If you use a DATA directive and the address is not even, WinAsm99 inserts a zero byte before the loop address, which breaks the sound list. Anyway, my method for calculating the MSB and LSB in this parenthesis free expression language works, but WinAsm99 has several undocumented features (e.g conditional assembly, longer labels) so it might have a secret way of getting the MSB and LSB of a labelled address.

 

Your embedding an address in your list.... Got it although I don't understand the math for the second byte. Seem like it should always be zero

Link to comment
Share on other sites

  • 2 weeks later...
This looks cool, too bad I do not have the skillset to use it.....


* The following source code is intended to be a support routine for

* SUPER-CART programmers who need stand-alone support for their programs

* which reside in the >6000 to >7FFF cartridge space. It definitely

* supports KSCAN, VSBW, VMBW, VSBR, VMBR, VWTR, DSRLNK, XMLLNK and

* GPLLNK and these have been proven to work. It also has a CIF routine

* which I haven't had an opportunity to test. Probably much of it could

* be weeded out to conserve space. The bulk of the routines were kindly

* sent me by David Romer and consist of the UTILEQU, UTILRAM, and UTILROM

* files which I understand to be part of the (public domain) TI-FORTH

* source code. I also note that these same files were incorporated into

* Tom Knight's TK-WRITER source code. My contributions to this routine

* consist of the blocks whose comments are mainly written in upper case

* and this entire file is meant to be released to public domain for use

* and redistribution by anyone who wishes it. I had trouble getting the

* GPLLNK routine to work and with the kind permission of Paul Charlton,

* have incorporated his GPLLNK routines from his Fast-Term program which

* do work in this environment. See program comments for more details.

* I would certainly appreciate any feedback or corrections anyone finds and

* I hope this is helpful. Enjoy! Jim McCulloch, 9505 Drake Avenue,

* Evanston, IL 60203-1107 (CIS 74766,500)

* ***********************************************************************

* SUPER-CART SKELETON ROUTINE: for SUPER-CART programmers to hang their

* routines on and flesh it out more. This version done 14 December 1985.

* ***********************************************************************

DEF PROG3,PROG4,PROG5,PROG6,PROG7,PROG8,PROG9

* THERE ARE SPACES FOR 9 MENU SELECTIONS WITH TI-BASIC

* AND E/A TAKING UP THE FIRST TWO. PROGRAMS 3-9 ARE

* YOURS.

AORG >6000 THIS IS THE BEGINNING OF THE SUPER-CART SPACE IN MEMORY

SCNKEY EQU >000E

XMLTAB EQU >0CFA XML tables (base)

PAB EQU >1000 PERIPHERAL ACCESS BLOCK

FLAG2 EQU >8349

FAC EQU >834A USED BY THE CIF ROUTINE AS WELL AS GPLLNK, ETC.

SCLEN EQU >8355

SCNAME EQU >8356

SUBSTK EQU >8373

STATUS EQU >837C GPL STATUS REGISTER

CRULST EQU >83D0

SADDR EQU >83D2

GPLWS EQU >83E0 GPL/EXTENDED BASIC workspace

PAD EQU >8300

VDPRD EQU >8800 VDP read data address

VDPSTA EQU >8802 VDP RAM status

VDPWD EQU >8C00 VDP write data address

VDPWA EQU >8C02 VDP write address address

R0LB EQU >83E1

R1LB EQU >83E3

R3LB EQU >83E7

GRMWD EQU >9C00 GROM/GRAM write data

GRMWA EQU >9C02 GROM/GRAM write address

GRMRD EQU >9800 GROM/GRAM read data

GRMRA EQU >9802 GROM/GRAM read address

DATA >AA01 VALIDATES THIS TO BE A VALID CARTRIDGE HEADER

DATA 0

DATA 0

DATA CHAIN POINTER TO DATA CHAIN WHICH SHOWS THAT THERE ARE MENU

* SELECTIONS TO BE DISPLAYED AND MADE

DATA 0

DATA 0

CHAIN DATA LINKA POINTER TO NEXT DATA LINK

DATA P9 LABEL POINTS TO BRANCH TO PROGRAM. NOTE THAT THE BOTTOM

* PROGRAM ON THE MENU DISPLAY IS PLACED FIRST AND THAT

* THEY THEN WORK UPWARD.

BYTE >04 NUMBER OF CHARACTERS TO BE DISPLAYED IN THE MENU LIST

TEXT 'EXIT' TITLE TO BE DISPLAYED IN THE MENU

P9 B @PROG9 BRANCH TO PROGRAM 9

LINKA DATA LINKB POINTER TO NEXT DATA LINK

DATA P8 POINTER TO PROGRAM BRANCH

BYTE >15 NUMBER OF CHARACTERS TO DISPLAY IN MENU LISTING

TEXT 'WIPE CARTRIDGE MEMORY' PROGRAM TITLE FOR MENU

P8 B @PROG8 BRANCH TO PROGRAM 8

LINKB DATA LINKC POINTER TO NEXT DATA LINK

DATA P7 POINTER TO PROGRAM BRANCH

BYTE >09 NUMBER OF CHARACTERS TO DISPLAY IN MENU LISTING

TEXT 'PROGRAM 7' TITLE TO BE DISPLAYED IN MENU

P7 B @PROG7 BRANCH TO PROGRAM 7

LINKC DATA LINKD POINTER TO NEXT DATA LINK

DATA P6 POINTER TO PROGRAM BRANCH

BYTE >09 NUMBER OF CHARACTERS TO DISPLAY IN MENU LISTING

TEXT 'PROGRAM 6' TITLE TO BE DISPLAYED IN MENU

P6 B @PROG6 BRANCH TO PROGRAM 6

LINKD DATA LINKE POINTER TO NEXT DATA LINK

DATA P5 POINTER TO PROGRAM BRANCH

BYTE >09 NUMBER OF CHARACTERS TO DISPLAY IN MENU LISTING

TEXT 'PROGRAM 5' TITLE TO BE DISPLAYED IN MENU

P5 B @PROG5 BRANCH TO PROGRAM 5

LINKE DATA LINKF POINTER TO NEXT DATA LINK

DATA P4 POINTER TO PROGRAM BRANCH

BYTE >09 NUMBER OF CHARACTERS TO DISPLAY IN MENU LISTING

TEXT 'PROGRAM 4' TITLE TO BE DISPLAYED IN MENU

P4 B @PROG4 BRANCH TO PROGRAM 4

LINKF DATA 0 NO MORE PROGRAMS IN THE CHAIN!

DATA P3 POINTER TO PROGRAM BRANCH

BYTE >09 NUMBER OF CHARACTERS TO DISPLAY IN MENU LISTING

TEXT 'PROGRAM 3' TITLE TO BE DISPLAYED IN MENU

P3 B @PROG3 BRANCH TO PROGRAM 3

WS BSS 32 WORKSPACE REGISTERS FOR MY PROGRAMS

SVGPRT DATA 0 Save GPL return address

SAVCRU DATA 0 CRU address of peripheral

SAVENT DATA 0 Entry address of DSR

SAVLEN DATA 0 Save device name length

SAVPAB DATA 0 Ptr into device name in PAB

SAVVER DATA 0 Version number of DSR

GRMSAV DATA 0 USED BY THE PREGPL AND GPLLNK ROUTINES

NAMBUF DATA 0,0,0,0

*

*** General utility workspace registers (Overlaps next WS)

UTILWS DATA 0,0

BYTE 0

R2LB BYTE 0

*

*** DSR link routine workspace registers (Overlaps prev. WS)

DLNKWS DATA 0,0,0,0,0

TYPE DATA 0,0,0,0,0,0,0,0,0,0,0

*

C100 DATA 100

H20 BYTE >20

EVEN

H2000 DATA >2000

DECMAL TEXT '.'

HAA BYTE >AA

CL BYTE >00 BYTE USED TO CLEAR @STATUS

EVEN

*

* Utility Vectors

*

GPLLNK DATA UTILWS,GLENTR Link to GROM routines

XMLLNK DATA UTILWS,XMLENT Link to ROM routines

KSCAN DATA UTILWS,KSENTR Keyboard scan

VSBW DATA UTILWS,VSBWEN VDP single byte write

VMBW DATA UTILWS,VMBWEN VDP multiple byte write

VSBR DATA UTILWS,VSBREN VDP single byte read

VMBR DATA UTILWS,VMBREN VDP multiple byte read

VWTR DATA UTILWS,VWTREN VDP write to register

DSRLNK DATA DLNKWS,DLENTR Link to device service routine

*

*===========================================================

* PRE-GPLLNK ROUTINE: THIS INITIALLIZES A POINTER USED BY THE

* GPLLNK ROUTINE. IF YOU INTEND ON USING GPLLNK IN YOUR PROGRAM,

* MAKE SURE YOU INCLUDE A "BL @PREGPL" STATEMENT SOMETIME BEFORE

* INVOKING GPLLNK. (ONLY NEEDS TO BE DONE ONCE.) THIS CODE WAS

* TAKEN WITH PERMISSION FROM PAUL CHARLTON'S FAST-TERM SOURCE CODE

* AND IS ALSO CONSIDERED BY THE AUTHOR TO BE PUBLIC DOMAIN.

*

PREGPL CLR R0 START AT THE BEGINNING

LI R8,>0F00 R8h=GROM XMLLNK op-code

LI R9,>F000 R9h=acceptable XMLLNK parameter

AGAIN MOVB R0,@GRMWA get GROM byte

SWPB R0

MOVB R0,@GRMWA

SWPB R0

MOVB @GRMRD,R1

NOP

AGAIN1 CB R1,R8 is it XMLLNK op-code?

JEQ FNDLNK yes, check its parameter

INC R0 no,

JNO AGAIN check next byte

BLWP @>0000 return to system monitor

*

FNDLNK INC R0 found XMLLNK op-code

MOVB @GRMRD,R1 get next byte

CB R1,R9 is it the right XML vector?

JNE AGAIN1 no - jump back to see if current byte is opcode too

*

DEC R0 found whole XMLLNK call

MOV R0,@GRMSAV put address where GPLLNK can find it

RT

*

*==========================================================

* LINK TO SYSTEM XML UTILITIES

*

XMLENT MOV *R14+,@GPLWS+2 Get argument

LWPI GPLWS Select GPL workspace

MOV R11,@UTILWS+22 Save GPL return address

MOV R1,R2 Make a copy of argument

CI R1,>8000 Direct address in ALC?

JH XML30 We have the address

SRL R1,12

SLA R1,1

SLA R2,4

SRL R2,11

A @XMLTAB(R1),R2

MOV *R2,R2

XML30 BL *R2

LWPI UTILWS GET BACK TO RIGHT WS

MOV R11,@GPLWS+22 Restore GPL return address

RTWP

*

*===========================================================

*** Link to GPL utilities

*

* THIS GPLLNK CODE WAS TAKEN WITH PERMISSION FROM PAUL CHARLTON'S

* FAST-TERM SOURCE CODE AND IS CONSIDERED BY THE AUTHOR TO BE PUBLIC

* DOMAIN. BEFORE YOU INVOKE GPLLNK IN YOUR PROGRAM ("BLWP @GPLLNK"),

* BE SURE YOU INCLUDE A "BL @PREGPL" IN YOUR PROGRAM TO ESTABLISH AN

* ADDRESS WHICH THE GPLLNK ROUTINE USES.

*

GLENTR MOVB @SUBSTK,R1 Fetch GPL subroutine stack pointer

SRL R1,8 Make it an index

AI R1,>8302

MOV @GRMSAV,*R1 Push XML address for return

SWPB R1

MOVB R1,@SUBSTK adjust stack pointer

MOVB *R14+,@GRMWA Set up address to call

NOP

MOVB *R14+,@GRMWA and second byte, adjusting return

NOP

LI R0,RTFGPL

MOV R0,@PAD

LWPI GPLWS

B @>006A

*

*** Return to assembly language from GPL

*

RTFGPL LWPI UTILWS Select utility workspace

RTWP Return to calling AL routine

*

*==============================================================

* KEYBOARD SCAN

*

KSENTR LWPI GPLWS

MOV R11,@UTILWS+22 Save GPL return address

BL @SCNKEY

LWPI UTILWS

MOV R11,@GPLWS+22 Restore GPL return address

RTWP

*

*==============================================================

* VDP UTILITIES

*

** VDP single byte write

*

VSBWEN BL @WVDPWA Write out address

MOVB @2(R13),@VDPWD Write data

RTWP Return to calling program

*

** VDP multiple byte write

*

VMBWEN BL @WVDPWA Write out address

VWTMOR MOVB *R1+,@VDPWD Write a byte

DEC R2 Decrement byte count

JNE VWTMOR More to write?

RTWP Return to calling Program

*

** VDP single byte read

*

VSBREN BL @WVDPRA Write out address

MOVB @VDPRD,@2(R13) Read data

RTWP Return to calling program

*

** VDP multiple byte read

*

VMBREN BL @WVDPRA Write out address

VRDMOR MOVB @VDPRD,*R1+ Read a byte

DEC R2 Decrement byte count

JNE VRDMOR More to read?

RTWP Return to calling program

*

** VDP write to register

*

VWTREN MOV *R13,R1 Get register number and value

MOVB @1(R13),@VDPWA Write out value

ORI R1,>8000 Set for register write

MOVB R1,@VDPWA Write out register number

RTWP Return to calling program

*

** Set up to write to VDP

*

WVDPWA LI R1,>4000

JMP WVDPAD

*

** Set up to read VDP

*

WVDPRA CLR R1

*

** Write VDP address

*

WVDPAD MOV *R13,R2 Get VDP address

MOVB @R2LB,@VDPWA Write low byte of address

SOC R1,R2 Properly adjust VDP write bit

MOVB R2,@VDPWA Write high byte of address

MOV @2(R13),R1 Get CPU RAM address

MOV @4(R13),R2 Get byte count

RT Return to calling routine

*

*===========================================================

* CIF - Convert integer to floating *

*

CIF LI R4,FAC Will convert into the FAC

MOV *R4,R0 Get integer into register

MOV R4,R6 Copy ptr to FAC to clear it

CLR *R6+ Clear FAC,FAC+1

CLR *R6+ in case had a string in FAC

MOV R0,R5 is integer equal to zero?

JEQ CIFRT yes - zero result and return

ABS R0 get ABS value of arg

LI R3,>40 get exponent bias

CLR *R6+ clear words in result that

CLR *R6 might not get a value

CI R0,100 is integer < 100?

JL CIF02 yes-just put in 1st fraction

* part

CI R0,10000 no-is arg < 100,2?

JL CIF01 yes-just 1 division necessary

* no - 2 divisions are necessary

INC R3 add 1 to exponent for 1st div

MOV R0,R1 put # in low order word for

* the divide

CLR R0 clear high order word for the

* divide

DIV @C100,R0 divide by the radix

MOVB @R1LB,@3(R4) move the radix digit in

CIF01

INC R3 add 1 to exponent for divide

MOV R0,R1 put in low order for divide

CLR R0 clear high order for divide

DIV @C100,R0 divide by the radix

MOVB @R1LB,@2(R4) put next radix digit in

CIF02

MOVB @R0LB,@1(R4) put highest order radix digit

* in

MOVB @R3LB,*R4 put exponent in

INV R5 is result positive?

JLT CIFRT yes - sign is correct

NEG *R4 no - make it negative

CIFRT RT

*

*===========================================================

*** Link to device service routine

*

DLENTR MOV *R14+,R5 Fetch program type for link

SZCB @H20,R15 Reset equal bit

MOV @SCNAME,R0 Fetch pointer into PAB

MOV R0,R9 Save pointer

AI R9,-8 Adjust pointer to flag byte

BLWP @VSBR Read device name length

MOVB R1,R3 Store it elsewhere

SRL R3,8 Make it a word value

SETO R4 Initialize a counter

LI R2,NAMBUF Point to NAMBUF

LNK$LP INC R0 Point to next char of name

INC R4 Increment character counter

C R4,R3 End of name?

JEQ LNK$LN Yes

BLWP @VSBR Read current character

MOVB R1,*R2+ Move it to NAMBUF

CB R1,@DECMAL Is it a decimal point?

JNE LNK$LP No

LNK$LN MOV R4,R4 Is name length zero?

JEQ LNKERR Yes, error

CI R4,7 Is name length > 7?

JGT LNKERR Yes, error

CLR @CRULST

MOV R4,@SCLEN-1 Store name length for search

MOV R4,@SAVLEN Save device name length

INC R4 Adjust it

A R4,@SCNAME Point to position after name

MOV @SCNAME,@SAVPAB Save pointer into device name

*

*** Search ROM CROM GROM for DSR

*

SROM LWPI GPLWS Use GPL workspace to search

CLR R1 Version found of DSR etc.

LI R12,>0F00 Start over again

NOROM MOV R12,R12 Anything to turn off

JEQ NOOFF No

SBZ 0 Yes, turn it off

NOOFF AI R12,>0100 Next ROM'S turn on

CLR @CRULST Clear in case we're finished

CI R12,>2000 At the end

JEQ NODSR No more ROMs to turn on

MOV R12,@CRULST Save address of next CRU

SBO 0 Turn on ROM

LI R2,>4000 Start at beginning

CB *R2,@HAA Is it a valid ROM?

JNE NOROM No

A @TYPE,R2 Go to first pointer

JMP SGO2

SGO MOV @SADDR,R2 Continue where we left off

SBO 0 Turn ROM back on

SGO2 MOV *R2,R2 Is address a zero

JEQ NOROM Yes, no program to look at

MOV R2,@SADDR Remember where we go next

INCT R2 Go to entry point

MOV *R2+,R9 Get entry address

*

*** See if name matches

*

MOVB @SCLEN,R5 Get length as counter

JEQ NAME2 Zero length, don't do match

CB R5,*R2+ Does length match?

JNE SGO No

SRL R5,8 Move to right place

LI R6,NAMBUF Point to NAMBUF

NAME1 CB *R6+,*R2+ Is character correct?

JNE SGO No

DEC R5 More to look at?

JNE NAME1 Yes

NAME2 INC R1 Next version found

MOV R1,@SAVVER Save version number

MOV R9,@SAVENT Save entry address

MOV R12,@SAVCRU Save CRU address

BL *R9 Match, call subroutine

JMP SGO Not right version

SBZ 0 Turn off ROM

LWPI DLNKWS Select DSRLNK workspace

MOV R9,R0 Point to flag byte in PAB

BLWP @VSBR Read flag byte

SRL R1,13 Just want the error flags

JNE IOERR Error!

RTWP

*

*** Error handling

*

NODSR LWPI DLNKWS Select DSRLNK workspace

LNKERR CLR R1 Clear the error flags

IOERR SWPB R1

MOVB R1,*R13 Store error flags in calling R0

SOCB @H20,R15 Indicate an error occured

RTWP Return to caller

*

**========================================================================

****USER-AVAILABLE PROGRAM SPACE***(WITH 2 OF MY UTILITIES TOSSED IN)

*

PROG8 LWPI WS PROG8 IS MY VERSION OF A UTILITY TO WIPE THE 8K RAM

* SPACE AND PLACE ZEROS AT >6000->7FFF.

WIPED DATA >02E0,>A000,>0201,>6000 THIS IS THE ACTUAL OBJECT CODE FOR A

DATA >0202,>2000,>0203,>0000 PROGRAM (AT AORG >A000) TO PLACE ZEROS

DATA >CC43,>0642,>16FD,>04E0 AT ADDRESSES >6000 TO >7FFF AND THEN

DATA >837C,>02E0,>83E0,>0420 BRANCH TO THE POWER UP ROUTINE. IF YOU

DATA >0000 DON'T HAVE 32K, I GUESS IT WON'T WORK.

LI R1,WIPED LOAD STARTING ADDRESS OF ROUTINE IN R1

LI R3,>A020 ADDRESS TO BE WRITTEN TO

LI R5,>11 NUMBER OF WORDS TO MOVE

LOOPF MOV *R1+,*R3+ WRITE A WORD

DEC R5 SUBTRACT A WORD FROM THE COUNTER

JNE LOOPF ARE WE DONE? IF NOT, KEEP ON GOING

BLWP @XMLLNK I KNOW, I KNOW... THIS WOULD BE MORE SIMPLY DONE BY A

DATA >A020 "B @>A020" BUT I WANTED TO DEMONSTRATE THAT THE XMLLNK

* ROUTINE WORKS. THIS EXECUTES THE WIPE OF CARTRIDGE RAM.

PROG9 CLR @STATUS PROG9 IS MY VERSION OF "OOPS, I DIDN'T MEAN TO BE HERE"

LWPI GPLWS GO TO GPL

BLWP @>0000 AND START OVER

* 1 2 3 4 5 6 7 8

*2345678901234567890123456789012345678901234567890123456789012345678901234567890

PROG3 B @PROG9 FOR YOUR PROGRAM, REPLACE THE "PROG3 B @" PHRASE

* WITH "COPY DSKn.PROGRAMx" (NOTHING IN LABEL FIELD)

* WHERE "PROGRAMx" HAS "PROG3" AS ITS STARTING POINT.

PROG4 B @PROG9 DITTO FOR THE REST, USING DIFFERENT "PROGx" AS START.

PROG5 B @PROG9 " " " " " " " " "

PROG6 B @PROG9 " " " " " " " " "

PROG7 B @PROG9 " " " " " " " " "

END

Link to comment
Share on other sites

  • 3 weeks later...

Does anyone have a code snippet for the equivalent of CALL FILES from assembler? I understand from the tech pages you need to call a subprogram >16 in the disk controller ROM.

 

Prior to calling DSRLNK with option 0Ah, you must set up a 2-byte PAB in VRAM with 0116h, put its address in PAD RAM at 8356h and store the number of simultaneous files you want to allow in PAD RAM at byte 834Ch. Off the top of my head, something like the following would probably work:
*
PAB    EQU  >1000           VRAM address of 2-byte Peripheral Access Block
NFILES DATA >0300           number of simultaneous files in left byte
PDATA  DATA >0116           DSR subprogram to run (FILES)
FILES  LI   R0,PAB
       LI   R1,PDATA
       LI   R2,2
       BLWP @VMBW           copy 2 bytes from PDATA (RAM) to PAB (VRAM)
       MOV  R0,@>8356       point to subroutine in DSR
       MOVB @NFILES,@>834C  #files argument for subroutine 016h
       BLWP @DSRLNK         call DSR with subprogram option
       DATA >0A
         .
         .
         . 

*

...lee

Link to comment
Share on other sites

  • 5 months later...

I am currently working on a project that requires the adding of two 16 bit numbers together, and I have a couple of questions:

 

  • Does the 32 bit result get stored in 2 adjacent memory locations? What if I am using registers and I add say R1 to R2, is the result then in R2 and R3 (a la MPY or DIV)?
  • How do I add two 32 bit numbers together using registers?

It's in these situations that I miss the ease of use of a high level language :?

Link to comment
Share on other sites

I am currently working on a project that requires the adding of two 16 bit numbers together, and I have a couple of questions:

 

  • Does the 32 bit result get stored in 2 adjacent memory locations? What if I am using registers and I add say R1 to R2, is the result then in R2 and R3 (a la MPY or DIV)?
  • How do I add two 32 bit numbers together using registers?

It's in these situations that I miss the ease of use of a high level language :?

 

Sixteen-bit addition (A) does not give a 32-bit result. You must check the overflow and carry bits to manage results that exceed a 16-bit representation.

 

For 32-bit addition, you would need a short routine that first added the right 16 bits, then the left 16 bits, while handling the overflow and carry bits for each addition to get the correct result. I'm sure someone here has done it. In fact, the floating point routines do a pretty good job with 8 bytes and a radix of 100. I can post the routine if that would offer any insight—even though it is not binary.

 

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Thanks for the pointers. I do now understand the concept and I can come up with the routine, but I found that I could get away with reducing the magnitude of the numbers by dividing them by 10 and thus keeping everything within 16 bits. This should not affect my application noticeably since I will be doing magnitude comparisons anyway. Besides, speed of computation is critical in my project and I want to minimize code gymnastics as much as possible.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...