Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

Set a breakpoint on writes to your R6 in Classic99 and it will stop and show you the instruction that is changing it. That should provide some insight.

 

So if you're at >70B8, then R6 is at >70C2, and the breakpoint syntax would be ">70C2" (in this case the '>' means 'write to').

 

I suppose that violates the pure original console concept though. ;)

Link to comment
Share on other sites

Set a breakpoint on writes to your R6 in Classic99 and it will stop and show you the instruction that is changing it. That should provide some insight.

 

So if you're at >70B8, then R6 is at >70C2, and the breakpoint syntax would be ">70C2" (in this case the '>' means 'write to').

 

I suppose that violates the pure original console concept though. ;)

 

Already had done that and it is totally the KSCAN call that is messing up R6. Here's the code snippet

PL LI,R7,1
 BL @DG
 BL @KI

DG MOV R11,R10
 LI R8,3
P1 MOVB @P(R6),R0
 SRL R0,8
 INC R6
 MOVB @P(R6),R1
 SRL R1,8
 INC R6
 BL @PP
 DEC R8
 JNE P1
 MOV R10,R11
 B *R11

KI MOV R11,R10
LP JMP LP
SA BLWP @>6020
<------  This is where R6 and R7 are getting trashed
 MOVB @>837C,R1
 LI R2,>2000
 COC R2,R1
 JNE SA
 MOV R10,R11
 B *R11

 

Up until the BLWP @>6020 (KSCAN), R6's contents are what they should be. Immediately after KSCAN, R6 is reset to zero for some reason and R7 to >FFFF. The DG routine changes R6, but these changes are not preserved after KSCAN....

 

As for violating the pure console concept, I have been violating that for a while now :) While everything is going through the LBLA, I am pretty much copying and pasting into Classic99 for routine testing purposes. That debugger has been a life saver. However, I am first putting all my code on paper with comments and notes. There is only so much pain I can endure :grin:

Link to comment
Share on other sites

Odd, but we know it's not the BLWP itself that's changing R6 and R7, that doesn't write to those user registers. Is that really where Classic99 breakpointed?

 

I don't have a proper test here, but I ran a quick and dirty loop:

 

  def start
  
start
  lwpi >70b8
lp
  blwp @>6020
  jmp lp
  
  end
The first thing I noticed was that the loader stored some data at >70D8, about 32 bytes worth (but oddly it was loaded into memory expansion at >a000... I didn't realize the Mini Memory knew about that ;) ).

 

When I ran it, something did alter >70B8 (R0, with the start address) and >70CE (R11, with >609C), but I don't see R6 and R7 of that workspace touched at all.

 

I reset and tried again with LBLA. I couldn't remember how to EXIT it, so I just used warm reset and ran the code from Easy Bug. Again, though, nothing was touching that workspace after it started - I set breakpoints over the whole space.

 

I think you might be chasing a red herring on looking at KSCAN...

Link to comment
Share on other sites

 

I think you might be chasing a red herring on looking at KSCAN...

 

 

I'm not sure how that would be given that R6 is fine up until that call... I'm including my entire code below. Copy and paste it into the LBLA and please double check me. You can run it from Easy Bug using E7D3C. To check for the R6 corruption, first remove the MOV R6,@TM at label RS and the MOV @TM,R6 a couple of instructions down. This will break the code because of the zeroing out of R6 after KSCAN. Maybe I'm missing something...

 

 

 AORG >7D3C 
 LI R0,>07F1
 BLWP @>6034
 LI R0,>0207
 BLWP @>6034
 LI R0,>0403
 BLWP @>6034
 LI R0,>03FF
 BLWP @>6034
 LI R0,>053E
 BLWP @>6034
 LI R0,>0603
 BLWP @>6034
 LI R0,>1F00
 LI R1,>D000
 BLWP @>6024
 LI R0,>1C00
 CLR R1
 LI R2,3
ST BLWP @>6024
 INC R0
 AI R1,>100
 JNE ST
 DEC R2
 JNE ST
 LI R0,>2000
 LI R1,>F100
 LI R2,>1800
CT BLWP @>6024
 INC R0
 DEC R2
 JNE CT
 CLR R0
 CLR R1
 LI R2,>1800
PT BLWP @>6024
 INC R0
 DEC R2
 JNE PT
 LI R0,2
 BLWP @>6034
 CLR R0
 MOVB R0,@>8374
 CLR R6
PL LI R7,1
 BL @DG
RS MOV R6,@TM
 BL @KI
 MOV @TM,R6
 CLR R7
 LI R1,6
 S R1,R6
 BL @DG
 MOVB @>8375,R8
 LI R9,>4400
 CB R8,R9
 JNE LT
 CI R6,54
 JNE PL
 CLR R6
 JMP PL
LT LI R9,>5300
 CB R8,R9
 JNE RS
 CI R6,6
 JNE ML
 LI R6,48
 JMP PL
ML LI R1,12
 S R1,R6
 JMP PL
DG MOV R11,R10
 LI R8,3
P1 MOVB @P(R6),R0
 SRL R0,8
 INC R6
 MOVB @P(R6),R1
 SRL R1,8
 INC R6
 BL @PP
 DEC R8
 JNE P1
 MOV R10,R11
 B *R11
KI MOV R11,R10
SA BLWP @>6020
 MOVB @>837C,R1
 LI R2,>2000
 COC R2,R1
 JNE SA
 MOV R10,R11
 B *R11
PP MOV R11,R9
 MOV R1,R4
 SLA R4,5
 SOC R1,R4
 ANDI R4,>FF07
 MOV R0,R5
 ANDI R5,7
 A R0,R4
 S R5,R4
 MOV R4,R0
 BLWP @>602C
 MOVB @M(R5),R2
 CI R7,0
 JNE SE
 SZCB R2,R1
 JMP CO
SE SOCB R2,R1
CO BLWP @>6024
 MOV R9,R11
 B *R11
M  DATA >8040,>2010
 DATA >0804,>0201
P  DATA >7FB2,>77BA
 DATA >87BA,>4BA0
 DATA >40A1,>4CAB
 DATA >3070,>266A
 DATA >297A,>393B
 DATA >3630,>2E3D
 DATA >6317,>680D
 DATA >5913,>9A17
 DATA >A413,>950D
 DATA >C43A,>CF3D
 DATA >C730,>CD70
 DATA >D47A,>D76A
 DATA >B2A0,>B1AB
 DATA >BDA1
TM DATA >0000
 END

 

 

 

All the program does so far is rotate a few dots around a center point using the S and D keys in bitmap mode. It's just a test for now.

Link to comment
Share on other sites

While I tried to debug your code, I found an evil bug in the debugger hooks in the TI MAME emulation ... The problem is that the debugger cleared the state of the cartridge ROMG line before the CPU has read the second byte.

 

This in fact led to lost bytes and illegal instruction states during debugging. It's working now, so I can continue to explore your fascinating issue. :)

  • Like 3
Link to comment
Share on other sites

While I tried to debug your code, I found an evil bug in the debugger hooks in the TI MAME emulation ... The problem is that the debugger cleared the state of the cartridge ROMG line before the CPU has read the second byte.

 

This in fact led to lost bytes and illegal instruction states during debugging. It's working now, so I can continue to explore your fascinating issue. :)

 

Ah a silver lining! Glad to be of service! :grin:

Link to comment
Share on other sites

I reset and tried again with LBLA. I couldn't remember how to EXIT it, so I just used warm reset and ran the code from Easy Bug. Again, though, nothing was touching that workspace after it started - I set breakpoints over the whole space.

Same for me at first ... it's easy: Typing END ends the LBLA.
  • Like 2
Link to comment
Share on other sites

Two important points I found:

 

First: Entering programs into the LBLA is a nightmare! :mad: I mistyped countless lines, and it seems there is just FCTN-3 to edit. Also, I skipped some lines while entering. At the end I got unresolved references, twice. This is the first time that I wished to have a way to paste text into MAME. Since that is not reliably possible, LBLA operation in MAME really means: type line by line - as with the real thing.

 

Then I finally remembered that I could also paste the program to a file on a disk image in TIMT, use the Assembler from E/A to assemble it, and then LOAD AND RUN it in MiniMem. Argh! Should have thought about that right away!

 

Second: Your workspace on entering the program is GPLWS, as the MAME debugger shows me. This will bring you into trouble for sure. Try to set it with LWPI.

Link to comment
Share on other sites

If, as @mizapf said, the default startup workspace is GPLWS (>83E0), you are definitely in trouble. The first thing that MM does after executing the “BLWP @>6020” is to change the WS from >7092 to GPLWS and, as I said in my last post, R6 and R7 are used quite a bit in KSCAN. Among other functions, R6 is cleared and is also used to return a status byte. Anyway—GPLWS is a bad idea as a user workspace.

 

...lee

Link to comment
Share on other sites

Thanks for the tip guys! I had assumed that MM automatically sets the user workspace to USRWSP (>70B8)... The MM manual states that USRWSP "is reserved for your program's set of workspace registers" but did not specifically state that I needed to set that up manually. Once I added LWPI >70B8, everything worked just fine without corruption of the registers.

 

 

The Morley book (Fundamentals of TI-99/4A Assembly Language - I taught myself assembly using that book) actually explains that it is true that >70B8 is indeed set as the USRWSP when the LBLA is loaded, however when we return to Easy Bug to run the program, the latter sets the workspace to >83E0 !

 

You'd think something that important would be mentioned in the MM manual, but oh no... We need to thin the hair of the hapless programmers a bit more...

  • Like 3
Link to comment
Share on other sites

Not really. It's where MM told me the user workspace was . Speed is not issue as things stand, but it's definitely an option if the need arises. At my assembly proficiency level, such considerations rarely bubble to my consciousness unless I hit a brick wall, in which case you guys on this forum have never failed to help me find a workable solution such as what happened above. So thank you!!!

Link to comment
Share on other sites

Two important points I found:

 

First: Entering programs into the LBLA is a nightmare! :mad: I mistyped countless lines, and it seems there is just FCTN-3 to edit. Also, I skipped some lines while entering. At the end I got unresolved references, twice. This is the first time that I wished to have a way to paste text into MAME. Since that is not reliably possible, LBLA operation in MAME really means: type line by line - as with the real thing.

 

 

Ah yes, good old fashioned suffering :grin: The LBLA is brutally unforgiving of typing mistakes, and downright Caligula-ish (ok I just invented that word for effect...) when it comes to correcting missed code lines. That pasting feature is one of the star features of Classic99 in my view. Have you considered incorporating that in MAME by any chance?

Link to comment
Share on other sites

The LBLA is brutally unforgiving of typing mistakes, and downright Caligula-ish (ok I just invented that word for effect...) when it comes to correcting missed code lines. That pasting feature is one of the star features of Classic99 in my view. Have you considered incorporating that in MAME by any chance?

 

This is not easy to achieve in MAME, carefully speaking. People using other emulations have already complained about that point as well. There is a paste feature, but it is not reliable. The problem is that such a paste feature must be handled by the MAME framework which controls the user interface. The MAME framework, however, is totally agnostic about the emulation it runs - consider that the framework (or the core, specifically) must be so generic to be able to handle thousands of widely different emulations from calculators to PlayStations.

 

If you think about TI BASIC, you remember that the more lines are in memory, the longer it takes to add more lines. There is no way for me in the TI emulation to signal to the framework that we're not ready to take more characters right now. And the framework cannot find out - it can't even find out when you're typing to fast. This is mainly a consequence of the fact that we are using original memory dumps for the console ROMs, and the console did not have a way to buffer keystrokes either or to detect an overrun. You could consider to patch the original ROMs to create something like an overrun indication, let's say, by setting a CRU bit, but still I don't know how to propagate that information to the framework. The longer one thinks about that, the uglier that concept becomes.

 

It is just for that reason that I added the paste feature to TIImageTool: The reason why you want to paste is - in most cases - to get a program into memory to save it afterwards. Instead, with TIMT, you save it to an image first, then run it in MAME. The effect is basically the same - I was able to paste any program that showed up in this forum into the image in TIMT, then use it in MAME. In contrast, pasting into the image is much safer, you can review the program code. Also, I added the BASIC cruncher to TIMT to be able to paste BASIC text into the image which ends up as a BASIC program. Works like a charm, if I may say so.

 

However, and this was the case here: The LBLA is a running program, and the keystrokes it receives are translated to object code in memory and do not end on disk. I could now either add this feature to TIMT again, which amounts to creating an assembler, or - as I said - remember that it's just source code that can be assembled by E/A.

  • Like 1
Link to comment
Share on other sites

Well I've got another one for you...

It appears that the LBLA does not like doing operations between 2 addresses symbolically. For example, the instruction C @X1,@X2 where X1 and X2 are labels to single words does not work. Neither does A @X1,@X2. Replacing one of the labels with the direct address or a register solves the problem.

Is this normal? I don't recall coming across that issue before with the EA...

Link to comment
Share on other sites

Well I've got another one for you...

It appears that the LBLA does not like doing operations between 2 addresses symbolically. For example, the instruction C @X1,@X2 where X1 and X2 are labels to single words does not work. Neither does A @X1,@X2. Replacing one of the labels with the direct address or a register solves the problem.

Is this normal? I don't recall coming across that issue before with the EA...

 

That's a bug in LBLA. See [http://www.stuartconner.me.uk/ti/ti.htm#minimem_lbla_bug].

Link to comment
Share on other sites

Well I've got another one for you...

It appears that the LBLA does not like doing operations between 2 addresses symbolically. For example, the instruction C @X1,@X2 where X1 and X2 are labels to single words does not work. Neither does A @X1,@X2. Replacing one of the labels with the direct address or a register solves the problem.

Is this normal? I don't recall coming across that issue before with the EA...

 

No, it is not normal. It works perfectly fine with E/A. [see @Stuart’s post before mine.]

 

...lee

Link to comment
Share on other sites

 

Thanks for the clarification. Interesting! Unfortunately I don't know if the LBLA can be patched in Classic99 though. I will definitely patch my tape though for the real thing. That said, I should be able to avoid the issue by simply defining my labels earlier in the program. I'll test it out later tonight.

 

Man I spent probably 2-3 hrs trying to figure out why these instructions were not working. Should have asked for help sooner...

 

UPDATE: Defining the data labels prior to the code section where they are used solved the problem and circumvented that bug.

Link to comment
Share on other sites

Awesome collaboration, glad you got it solved1

 

Mizapf, regarding "there is no way to know" when it's safe to paste another byte, there is a way There is actually a string paste function in the PS/2 adapter I created -- which is a separate piece of hardware that needs to interface to a real TI.

 

All you need to do is count how many times the column changes. When it has changed as many times as there are possible columns (I believe I used 8), you can be reasonably sure that at least one scan has completed. True that this is not 100% and software could be written that it's not compatible with -- but this software is very unlikely to be able to receive a generic pasted string. My code uses this sequence to establish a 'frame'. It holds the character being pasted for one frame, then it leaves the keys off for one frame. This means it pastes at the rate that the calling software is scanning the keyboard (possibly slightly slower).

 

Classic99 of course knows which ROM is loaded, and for its paste function it actually watches for KSCAN and injects the code directly. This is not so much in line with the MAME approach... but as you do have fixed CRCs for every ROM, you arguably DO know what's loaded. ;)

 

Both mechansims actually work in Classic99, because Classic99 runs the microcontroller code from my PS/2 interface. If the backend did have a way to specify that you are ready for a pasted key, you can certainly implement such a mechanism.

 

(To see the PS/2 paste string, enter the Konami code on the keyboard while in any editor or TI BASIC. Works in Classic99 or on the hardware adapter: up, up, down, down, left, right, left, right, B, A, Enter.) ;)

  • Like 1
Link to comment
Share on other sites

 

Thanks for the clarification. Interesting! Unfortunately I don't know if the LBLA can be patched in Classic99 though. I will definitely patch my tape though for the real thing. That said, I should be able to avoid the issue by simply defining my labels earlier in the program. I'll test it out later tonight.

 

Man I spent probably 2-3 hrs trying to figure out why these instructions were not working. Should have asked for help sooner...

 

The disk file MM_LBLA.OBJ is a windows-formatted text file in the TI uncompressed object file format. You could probably find the correct byte to patch there. Likewise, if you apply the patch in easy bug, again, it will be saved with the rest of the NVRAM until you wipe it. ;)

Link to comment
Share on other sites

 

The disk file MM_LBLA.OBJ is a windows-formatted text file in the TI uncompressed object file format. You could probably find the correct byte to patch there. Likewise, if you apply the patch in easy bug, again, it will be saved with the rest of the NVRAM until you wipe it. ;)

 

I took a quick look at the object file, but it does not quite match the memory contents of the MM after LBLA is loaded and I can't seem to find the right string to change in it. I do know however that the file represents the entire 4K of the MM from >7000 to >7FFF, so it will likely be just a matter of counting bytes as long as I understand how the file is formatted. I see that each line is terminated by 80000F. Is that correct?

Link to comment
Share on other sites

Hi Tursi,

 

thank you for your tips indeed; these are some interesting thoughts, and I already copied them into a file before it gets lost in the stream of postings ... ;)

 

I'm still not overly optimistic, but as I said, there is a general wish of MAME users that such a feature be available at some time. I could imagine that eventually, there will be some core feature for throttling input, and this will them be available to the emulated system in some way.

 

In the current state, my concerns are that such a concept must also work e.g. for the Geneve, and you have so many different configurations ... It's not so great to see that the pasting is working correctly on the 99/4A, but then not for the 99/8 or the Geneve. Here, you're always in a more comfortable situation with Classic 99, since it is a TI-99/4A-only emulator, and you can assume safe ways to retrieve meta-information (what is the system doing) and to monitor activity.

 

For now, the paste feature in TIMT is doing almost everything I need. It is certainly not an optimal solution; I suppose most people don't remember TIMT as a practical way in that situation and just wonder why MAME is not offering such a feature.

Edited by mizapf
Link to comment
Share on other sites

 

I took a quick look at the object file, but it does not quite match the memory contents of the MM after LBLA is loaded and I can't seem to find the right string to change in it. I do know however that the file represents the entire 4K of the MM from >7000 to >7FFF, so it will likely be just a matter of counting bytes as long as I understand how the file is formatted. I see that each line is terminated by 80000F. Is that correct?

 

I've attached a corrected version.

MM_LBLA_CORRECTED.rar

  • Like 1
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...