Trying to understand vi65

Discuss all aspects of programming here. From 8-bit through to modern architectures.
Post Reply
User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Trying to understand vi65

Post by pau1ie » Fri Nov 02, 2018 12:31 am

Ive compiled the code, and can't get anything to display, (It displays the empty lines) but apart from that it does seem to work to an extent.

Ive been debugging it using the b-em debugger, trying to work out where the "--empty--" text would be written. I'm looking at v0.1 in the hope it would be easier to understand, and notice in a.asm there is a procedure emptybuf which stores the location if nolinetxt (But -4 for some reason) into the displaylow procedure by calling setstatus. But then it does weird things

So in file a.asm here: https://sourceforge.net/p/vi65/code/HEA ... v0.1/a.asm

At line 1740, Why is it doing

Code: Select all

		sta registers.first+registers.file
		sta registers.last+registers.file
This compiles to
sta $254e ; registers.file (See below), so why registers.first?
sta $2550 ; No idea what is going on here.

Here is a portion of the dasm compiled code from the part where registers is defined near the end of the file, which also confuses me because it has a similar construct which seems to produce different results.

Code: Select all

>2542		00 00				newline		.word registers.nl
>2544		00 00						.word registers.nl
>2546		00						.byte 0
=9550						prgend		= registers+registers.file
.2547						registers
=9543						first		= *+0
=9545						last		= *+2
=9547						len		= *+4
=9548						lines		= *+5
>2547	0000	42 25				nl		.word newline
>2549	0002	42 25						.word newline
>254b	0004	00						.byte 0
>254c	0005	01 00						.word 1
>254e	0007					file		.fill 7
>2555	000e					unnamed		.fill 7
.255c						registersend
.255c						marks
=$255c						line		= *
=9566						column		= *+2
>255c	0000							.fill 3*26		;a-z
>25aa	004e					start		.fill 3
>25ad	0051					end		.fill 3
.25b0						endmarks
.25b0						references
=9648						next		= *+0
=9650						prev		= *+2
=9652						len		= *+4
=9653						reg		= *+5
>25b0	0000					load		.fill 6
>25b6	0006					temp		.fill 6
>25bc	000c					start		.fill 6
>25c2	0012					end		.fill 6
>25c8	0018					insert		.fill 6
>25ce						filename	.fill width-2
>25f4						zpsave		.fill zpend-zpstart
.261a						memory
I don't understand where the =95?? and =96?? addresses are coming from. It looks like it wants to write to these addresses, but this is paged rom area.

So I suppose my questions are:
What is the expression that looks like it is adding two addresses trying to do (e.g. registers+registers.file)
Are the numbers e.g. 9550 in the first column of above addresses
If so, where do they come from, and how do I change them to something more sensible.

I have changed the program slightly, maybe I should upload it to github.
I'm working on http://bbcmicro.co.uk

User avatar
jgharston
Posts: 3244
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Trying to understand vi65

Post by jgharston » Fri Nov 02, 2018 9:10 am

Maybe it really does need all that memory. If you target a system with sideways and shadow RAM, you can get 48K of program space by forcing a shadow screen mode and selecting an empty bank of sideways RAM, giving you &0000-&BFFF as working memory. Note that you won't be able to load/save the bit at &8000-&BFFF as the filing system will be paged in at that point, so you'll need to use OSGBPB via a buffer.

I read through the code last week and got thoroughly confused. :(

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

acorn
Posts: 13
Joined: Fri Dec 23, 2016 10:18 am
Contact:

Re: Trying to understand vi65

Post by acorn » Fri Nov 02, 2018 10:05 am

pau1ie wrote:
Fri Nov 02, 2018 12:31 am
I don't understand
I have changed the program slightly, maybe I should upload it to github.
Hi!

The original author is still active (ie. organizes the annual Arok Party). Perhaps he is in the best position to help you along with the port: soci on c64.rulez.org (from a.asm).

https://csdb.dk/scener/?id=3603

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Fri Nov 02, 2018 2:39 pm

jgharston wrote:
Fri Nov 02, 2018 9:10 am
Maybe it really does need all that memory.
I assumed that memoryend at line (say) 173 told it where the memory ends, and the *=801-2 at line 170 says where to start. I copied this section and put some numbers in that seemed sensible for the BBC B. There is some use of zero page, and seems to be some other bits of memory allocated, which I moved to places which are used by Basic, so hopefully will be available for this. What I am confused about is were the assembler gets this number from, as I can't see it being assigned anywhere.
jgharston wrote:
Fri Nov 02, 2018 9:10 am
I read through the code last week and got thoroughly confused. :(
I feel better that it isn't just me, but then again if you are confused, maybe I am more foolish than I thought to use this as a way to learn assembler!
acorn wrote:
Fri Nov 02, 2018 10:05 am
The original author is still active
Thanks - I might try that.
I'm working on http://bbcmicro.co.uk

User avatar
jgharston
Posts: 3244
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Trying to understand vi65

Post by jgharston » Fri Nov 02, 2018 8:19 pm

In a couple of weeks I'll have 15 hours to kill on an aeroplane, so I could have a bash at it then.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Mon Nov 05, 2018 11:22 pm

I'm still staring at this.

There is text that gets displayed in the status line at 'banner'.
This is referred to in displaytxt.asm at displayinit.
This calls setstatus which stores the two bytes of the address in displaylow.st1 and st2.
Then it calls the display subroutine, which is back in a.asm. I guess this is what is supposed to paint the screen from the buffer - I suspect I will have to look at this in more detail later.
Then it jumps to displaylow, which is the part I am interested in because that is where the address of the message to display has been written. I am not sure what it does in the first few lines, (Stores the start of the screen in a variable "screen")

Anyway, when it gets to the part I am interested in, it just writes them to currentline, and jumps to paintone.
Now, paintone refers to a cache variable at $0800 in the apple. "Inside the apple II" tells me this is page2 of video memory used for displaying the secondary text screen, but this is rarely used. I had assumed then that this was just being used for memory, but maybe it is supposed to be used for screen memory.

Looking down the paintone procedure I see a lot of if statements. I haven't worked out what they are all for, so haven't filled in the BBC ones. I suppose it shouldn't be surprising I don't get anything displayed! I'll have to look at this in more detail later.
I'm working on http://bbcmicro.co.uk

Coeus
Posts: 1078
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: Trying to understand vi65

Post by Coeus » Tue Nov 06, 2018 10:33 pm

pau1ie wrote:
Mon Nov 05, 2018 11:22 pm
Anyway, when it gets to the part I am interested in, it just writes them to currentline, and jumps to paintone.
Now, paintone refers to a cache variable at $0800 in the apple. "Inside the apple II" tells me this is page2 of video memory used for displaying the secondary text screen, but this is rarely used. I had assumed then that this was just being used for memory, but maybe it is supposed to be used for screen memory.
...
I did have a look at vi65 briefly when it was first mentioned. My initial impression was that most of the ports run bare on the hardware, i.e. they read the keyboard, perform key bounce and repeat logic and write characters to screen memory rather than using an OS.

So it seems to me there are three options for this display code:

1. Add to the conditional compilation in displaytxt.asm to create a version for the Mode 7 screen.
2. Add to conditional compilation in one of the displaygfx modules for one of the non-mode-7 screens.
3. Create a display module that uses the BBC MOS for text output and which can therefore work in any mode.

Assuming option 3 performs well enough it should be the best one as it is the most flexible. Not only does it give the user a choice of modes it would also work with screen shadow memory on the Master and B+ That means you don't necessarily need to understand how the subroutines in any of the existing display modules work, just what they are expected to do so you can write a version that is specific to the BBC. For example, paintone may just be a call to OSWRCH if the 'one' refers to one character.
Last edited by Coeus on Tue Nov 06, 2018 10:34 pm, edited 1 time in total.

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Wed Nov 07, 2018 9:36 am

Y
Coeus wrote:
Tue Nov 06, 2018 10:33 pm
So it seems to me there are three options for this display code:
Yes, I intend to try something between 1 and 3, i.e. target mode 7 to start with but use the MOS where possible. Then it would work on other modes apart from the width and height are hard coded. This could be dealt with later. As you say it seems to write directly to screen memory, so I thought it would work in mode 7, already. As I say, I do get it to write the dashes (There is no tilde in mode 7) for blank lines, so I am not sure what is going wrong here.

I am pretty sure I have got input at least partially working because if I press "I" and trace with a debugger it calls the insert procedure.

I am trying to understand what it is doing at present so I can adapt it. It is slow progress because I am learning as I go.
I'm working on http://bbcmicro.co.uk

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Wed Nov 07, 2018 11:12 pm

Had another look this evening. The string is "vi65 soci/singular" and it is supposed to be displayed in the status line once vi65 initialises. This happens at paintone.m1 in displaytxt.asm. "lda (currenttext),y" where currenttext is the start of the string, and y is the position we are concerned with (the 'v' in this case) This enters a load of conditinal compilation. Apple2 would EOR it with 80 (To make sure it is 7 bit) Others do more complicated things. I haven't changed this part, so it does the commodore stuff, and at the end a contains $16, which is a control code. I suspect this is why nothing is being displayed. Indeed it is written to the current memory location at sta (screen),y after the APPLE2) && width==80 conditional.

So I need to add a BBC part of the IF statement after m1 that does nothing (Maybe eventually it needs to ensure control characters don't mess anything up), and I will get something on the screen.

I am using the debugger in b-em. I found breakr useful to break on read of the string. I got the memory address from the dasm file which is created as part of the compilation.

I'm busy tomorrow, so probably the next chance to play with this will be abug.

[Edit - typos!]
Last edited by pau1ie on Wed Nov 07, 2018 11:14 pm, edited 1 time in total.
I'm working on http://bbcmicro.co.uk

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sat Nov 10, 2018 6:05 pm

That worked - I now display the text on the status line. It is in upper case, until I removed the -a from the TASS command line. Nothing else happens on screen though.

I think I would like to try moving the cursor next. At present it stubbornly stays where it was when the *vi command was run. It should be at the top left of the screen. I guess the place to start looking is displaytxt.asm at the cursor procedure. I think it is just writing the cursor directly to screen memory. The apple 2 version writes to c00f to enable the alternative character set which allows inverse characters, maybe that is what it is using as a cursor, which is why (So far as I can see) it loads the location, does an EOR with 128 then stores it again. So I probably just need to remove all that and just use the OS routine to move the cursor, probably using VDU codes.

That worked!

Next I think I want to see why when I press "I" I don't see a change in the status line (I think it should say "-- insert --")
I'm working on http://bbcmicro.co.uk

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sat Nov 10, 2018 10:31 pm

Procedure keylookup is responsible for controlling what happens on a key press. This is a bit clever because there is an array of keys to search and an array of procedures to call based on the key. It pushes the address of the procedure to call on to the stack as if it was done by a jsr, then returns. When I press "i" on my keyboard, caps lock is on in b-em, so it gets an I, which should call kI, which is in insert.asm.

When I get to keylookup, A contains $49, which is I, so I got something right! It searches through the array to find I, which it does, and jumps t kI as predicted. So far so good!

It decrements tochar.mode. Is this how it records edit or insert?

It jumps to motion_uparrow - This procedure is actually the procedure for the caret key and moves the cursor to the first non blank character of the current line, which will be tricky because there is no text in the editor, but it decides column 0 is the correct place to be.

Then it falls through to insertmode and sets the status line memory address in x and a, and calls setstatus, which just writes the address of the message in the displaylow.st1 and st2, which as I found earlier is written by displaylow.

Then it calls setmark, which marks the current position. (as if you had done m)

Then it falls back to the loop which waits for a keypress. The screen hasn't been updated.

Not a lot has happened between setstatus and waitkey, there should be a display in there. I see in the apple conditional it calls display and cursorup repeatedly while in the loop waiting for a keypress. I expect that is what I am missing.

Brilliant! It works. The cursor goes down the screen rather than across, but I can fix that! I can press keys and see output!

Next I will try and get the cursor to stay in the right place.
I'm working on http://bbcmicro.co.uk

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sat Nov 10, 2018 10:58 pm

That was quite easy, I just needed to swap x and y. This vi is the type where it scrolls the display right if you go past the end. The cursor doesn't keep up if I do that. I suspect it also doesn't work if I scroll down past the end of the page, but I think I want to get the first screen working first of all.

Next I need to try to get escape to work. At the moment it just inserts a box. That will wait till tomorrow - I think we are about to be kicked out...
I'm working on http://bbcmicro.co.uk

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sun Nov 11, 2018 9:47 pm

To get escape working. I understand that there is an error which you have to clear when escape is pressed (Though I could disable this with osbyte &c8). This is done and the program continues, but it just inserts a square into the buffer which is ascii FF. This is because I had assumed that osbyte wouldn't mess with the registers, but it does. Saving a on the stack and restoring it afterwards, and now escape works.

I do get rubbish over the screen (Code counting down and moving the cursor to the right) if I hit keys that shouldn't do anything. I have an R on the screen in memory location 7c57 which is just about to be overwritten, so if I breakw on that location I should find the culprit It is the cursor attempting to move.

That took ages to debug. I was overwriting an instruction because I thought cursor.size was allocating memory, but actually it was just a pointer, so it was overwriting an instruction rather than its argument. I don't use this at the moment as I am not sure you can change the cursor size in mode 7.

So now it seems to be working pretty well. issues are pressing 9 inserts l, cursor position is incorrect on the screen unless you are at the start of the file (I assume I am using the offset from the start of the file rather than the start of the screen). Colon and delete don't work. I haven't even looked at load and save, so they won't work either. But pretty much everything else does work, so I am pleased with progress.
I'm working on http://bbcmicro.co.uk

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sun Nov 11, 2018 11:38 pm

9 doesn't work because it triggers the code for control-y. Control-y is defined as asc(y)(=121)-k_control (where k_control is 64), which is 57. Character "9". I need character 25, control needs to be 121-25 = 96 (hex 60). This is another area I had let default to commodore. I suppose I should check the values of the remaining key codes.
I'm working on http://bbcmicro.co.uk

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Sun Nov 11, 2018 11:47 pm

Now 9 and delete work. I need to change the cursor keys so they return keycodes rather than selecting text to copy.
I'm working on http://bbcmicro.co.uk

User avatar
pau1ie
Posts: 586
Joined: Thu May 10, 2012 9:48 pm
Location: Bedford
Contact:

Re: Trying to understand vi65

Post by pau1ie » Tue Nov 13, 2018 12:00 am

I want to work out how to find the current cursor position on the screen. I know that line and column contain the line and column of the cursor with respect to the start of the file, so works initially.

Some reading of the source reveals that cursor.in+1 has the x location, and paintone.u+1 has the y location. Now the cursor stays in the correct place on the screen even when scrolling.

Next I would like to get the colon command working.
I'm working on http://bbcmicro.co.uk

Post Reply