Jump to content
InsaneMultitasker

Geneve OS development discussion

Recommended Posts

This topic is intended for discussing development of the Geneve 9640 operating system (known historically as MDOS).

 

Release history: 

image.png.00c0c89e0e5c4fd411bdf5834be4692e.png

 

DOWNLOADS:

Link to Ninerpedia article containing the most recent v6.50 Release disk: 

Booting MDOS from Horizon Ramdisk - Ninerpedia

 

Current development goals include: 

1. Identify the most recent, stable source code files; recreate bug fixes as necessary

2. Integrate the TIPI development and the 6.70/7.00 development 

3. Release an updated OS 

4. Release the updated source code

 

 

 

UPDATES :

A long-standing barrier to releasing the next stable OS was a disk IO corruption bug that has recently been identified and (seemingly) corrected.  (RESOLVED)

18 Jan 2021 - Combined 7.00 source base with TIPI support routines. SCSI Cache bug resolved.  Organized/cleaned up source and MAKE file structures. Built OS using HRD4000B w/ram hardrive routines.  v7.20

22 Jan 2021 - Investigated DSR data/buffer routines. Delays are induced when copying data from the device to internal buffers to the task.  No problems identified; there are possibilities for enhancements at a later date.

23 Jan 2021 - Added link to MDOS 6.50 release disk.  Implemented TIPI DSK1-4 mapped drives; fully functional from native OS command line and level 3 functionality in /4a (GPL) mode.

 

 

Current OS Memory Map:

image.thumb.png.353f9d5bbf6c33003f14e991b7a95ac4.png

  • Like 9
  • Thanks 1

Share this post


Link to post
Share on other sites
On 1/10/2021 at 8:33 AM, arcadeshopper said:

Can you fix cd to be more predictable. I can probably get some examples today if needed.
 

Yes, please.  There are some limitations to CD and other commands due to available space in that segment of the OS. (16 bytes free!)  We've removed DISKCOMPARE and DISKCOPY to free up some space in the command line interpreter, which might allow for some feature adds/corrections after a bit more analysis is completed.

  • Like 4

Share this post


Link to post
Share on other sites

It is predictable from what I see here.

 

CD does not check whether the path exists; this has always been the case. Would be nice if it did, but takes more time. On the right, the trailing slash should be removed. The bad thing is that DIR requires the trailing slash.

 

DIR MODULES will not deliver the contents

DIR MODULES\ does it

 

CD MODULES is OK

CD MODULES\ will fail.

Share this post


Link to post
Share on other sites

In the example on the left, you got the device error because you typed "module", not "modules" with the latter being the correct folder name. And sorta along the lines with what was posted above, the trailing slash was after the directory name was converted to a period so that "modules" became "modules." which that folder does not exist either.

 

The CMD.exe window for Win10 allows one to:

 

cd down\ to go to C:\>DOWN

 

or

 

cd down. to go to C:\>DOWN

 

One route would require stripping a trailing "." or trailing "\" from the path request.  Another option is to strip and error report and revert back to the original path if an invalid entry is made similar to what a MS-DOS prompt would do.  

 

This is worth documenting as an improvement "as time permits" as it would likely require changes in a number of places in the CLI code for consistency sake across a number of commands impacted. 

 

 

 

 

 

 

 

Edited by BeeryMiller

Share this post


Link to post
Share on other sites

Happy Monday.

image.thumb.png.4b9d610b56a39124a918b82997b54e0a.png

MDOS 7.00 code base integrated with our TIPI work from the past month.  

Took the time yesterday to delete/organize the source folders.

Compiled this morning using HRD4000B and ram hard drive support. 

Includes TIMODE2 alternative which frees up the dedicated MyWord ram (64k) for use. 

 

  • Like 9
  • Thanks 2

Share this post


Link to post
Share on other sites

Testing a few powerup routine configurations within the OS that impact the /4a and Geneve OS modes. 

GPL/TIMODE now uses the color defined by the command line (if in text 40/80 mode) instead of the default white on blue.  (No, I do not prefer white on red) ;) 

Took a stab at bridging the gap between GPL interpreter and TIMODE.  The function of the "GPL" program isn't to interpret GPL, it is to provide a TI-99/4a compatible environment. 

Options area might need to be reworked and/or changed to 80 columns at a future date.

 

image.thumb.png.76d39377ccbb5d4df58d4817419966db.png

 

  • Like 6

Share this post


Link to post
Share on other sites

The past few evenings I researched a long-standing curiosity (and mild concern) of mine, with respect to the Geneve OS and its master DSR.

 

Someone once told me that loading files from the SCSI card using its on-card DSR was faster than the OS's master DSR, and that it was most noticeable when loading a cartridge via GPL.  The difference is relatively simple to observe:  Load MDOS 6.50 and GPL 6.50;  load a cartridge such as Extended BASIC;  Engage ROMPAGE mode and load the cartridge again.  The latter load will be faster.

 

That comment spurred me into reworking some of the SCSI DSR code and adding a sector cache to improve overall performance.  Those changes improved read IO speeds considerably, however, the changes only impacted certain operations.

 

MDOS 7.0 tweaked the Ramdisk and PFM IO to use word-based moves, and now mimics some of the fast copy ideas learned from reading Tursi's and Asmusr's posts (among others), such as unrolling critical loops to 4x or 8x operations per loop.

 

Even with these changes, loading programs from the OS command line still exhibits a slight delay between each file load.  Pasts attempts to find the bottlenecks were unsuccessful because I was not looking in all the right places.

 

Tracing the code we find that the OS loads each chained file (16k max per file) from disk to a staging area of two consecutive 8k pages.   Next, the OS inspects the header for the load address and file size.  It checks for the encryption status and if the file is encrypted, the OS decrypts the data.   The OS then copies the (decrypted) program data into the new task's pages.  This operation is completed one byte at a time using MOVB between the OS buffer and the new task, with comparisons for all respective boundaries for each byte.

 

To load a program from a device such as the SCSI card, we must account for any data copies from device to task.  Surprisingly, the OS must copy the data FOUR times on its journey from the device to the task  (five times if decryption is required): 

 

Device->internal DSR disk buffer->internal DSR local buffer->internal OS task buffer/staging area (PASDAT)->decrypt (if needed)-> task's destination memory

 

The buffer copies are typically MOVB loops since the source and target data may exist on even or odd boundaries. Slow RAM is typical for the source and target memory, and the majority of the DSR executes from slow RAM.

 

The BREAD and BWRITE routines are faster since the final buffer inspection/move is not required.  The PAB specifies the task's buffer address; the DSR moves the data to/from the buffer directly.  The IO operation looks something like this: 

 

  Device->internal DSR disk buffer->internal DSR local buffer-> task buffer (PASDAT)

 

GPL mode uses VDP RAM within the local task space, which to some extent is faster if only because the copy requires minimal paging interaction, however, as with the Geneve program and like all TI program image loaders, the files must still be inspected:

 

  Device->internal DSR disk buffer->internal DSR local buffer-> VDP memory location for the image file (PASDAT)-> Opt 5 loader copies from VDP to CPU ram destination memory

 

 

I'm not implying there is a problem with the OS nor that the data transfer rate is unacceptable.  And while there is some potential for additional improvement in the future, the important thing is that we can explain why the slight file IO delays exist.  OS overhead is the primary reason for the induced delays.

 

Lastly, a performance tip for those of you writing native OS based programs:  locate your data buffers on even word boundaries.  Doing this enables the OS to use 16-bit word copies (MOV) between the DSR buffer and task memory, and cuts the iterations in half.

 

 

 

 

  • Like 8

Share this post


Link to post
Share on other sites

> It checks for the encryption status and if the file is encrypted, the OS decrypts the data.  

 

I didn't know Geneve OS has Encryption?

Share this post


Link to post
Share on other sites

Geneve programs can be encrypted, not MDOS, to prevent sector editing of the program.

Share this post


Link to post
Share on other sites

>Geneve programs can be encrypted, not MDOS, to prevent sector editing of the program.

 

Beery,

  Are you the keeper of the MDOS manual?

  Do you have an 'up2date' Myarc Advanced Basic Manual? (I tried to keep up with the change this page, change that page program, but I'm not sure I was totally successful....)

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, dhe said:

>Geneve programs can be encrypted, not MDOS, to prevent sector editing of the program.

 

Beery,

  Are you the keeper of the MDOS manual?

  Do you have an 'up2date' Myarc Advanced Basic Manual? (I tried to keep up with the change this page, change that page program, but I'm not sure I was totally successful....)

 

Keeper of the MDOS manual, no.  If anyone has anything beyond a PDF of the original manual, I am not aware.

 

Jim Uzzell released his updates to various pages of the Advanced Basic Manual but nothing along the lines of a full text editable manual I have seen.  I have attached the pages Jim updated to this message.

MYBMAN.ZIP

  • Like 5
  • Thanks 1

Share this post


Link to post
Share on other sites
12 hours ago, BeeryMiller said:

Geneve programs can be encrypted, not MDOS, to prevent sector editing of the program.

What a mean thing to do!! :lol:

 

 

  • Like 2
  • Haha 3

Share this post


Link to post
Share on other sites
16 hours ago, BeeryMiller said:

Geneve programs can be encrypted, not MDOS, to prevent sector editing of the program.

 

Unless it is widely used, I'd recommend removing that feature.

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
6 hours ago, jedimatt42 said:

 

Unless it is widely used, I'd recommend removing that feature.

There are programs that use the encryption.

 

Beery

  • Like 1

Share this post


Link to post
Share on other sites
On 1/23/2021 at 2:58 PM, BeeryMiller said:

Geneve programs can be encrypted, not MDOS, to prevent sector editing of the program.

That's new to me. How do you specify the encryption in the PAB?

  • Like 1

Share this post


Link to post
Share on other sites

I wonder if Tim exercised the code that had the comments: YALF, YAPF... Those where always good for a laugh!

Share this post


Link to post
Share on other sites
2 hours ago, mizapf said:

That's new to me. How do you specify the encryption in the PAB?

Encryption was not done in the PAB, rather, a separate program that was released to be used by everyone.  There was also an unencrypt program someone wrote and released as well.

 

The first byte or two were modified of the program image file.  It's been awhile, so I do not know how the flag(s) were arranged.  Off the top of my head, I do not recall if it is in the DSR where the unencryption code was embedded, or whether  the encrypted programs were only loadable from the CLI and it unencrytped the program.

 

Beery

 

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, BeeryMiller said:

 Off the top of my head, I do not recall if it is in the DSR where the unencryption code was embedded, or whether  the encrypted programs were only loadable from the CLI and it unencrytped the program.

 

Beery

 

The decryption routine is in L9.LOADF2S and is signaled by the load address.   Unraveling the obfuscation (de-cryption)  is the inverse, shift, xor sequence in the source below.  John Johnson wrote a program called ENC that encrypts a decrypted program or decrypts an encrypted program, rendering the encryption moot back in the day.  The GPL program might be encrypted by its special linker, if I remember correctly, though I might have eliminated that from the process.  I'll have to look.  ENC pretty much halted most future use of this process.   

 

LOAD04 LI   R7,>A002
       MOV  *R7+,R5           length of this file
       MOV  *R7+,R4           load address
*
       MOV  R4,R6
       ANDI R4,>FFFE   
       C    R6,R4

       JEQ  LOAD07
*
       MOV  R5,R2

 

LOAD05 MOV  *R7,R1   "decrypt" the image file
       INV  R1
       SRC  R1,11
       XOR  R7,R1
       MOV  R1,*R7+
       DECT R2
       JGT  LOAD05

Share this post


Link to post
Share on other sites
3 hours ago, dhe said:

I wonder if Tim exercised the code that had the comments: YALF, YAPF... Those where always good for a laugh!

All comments are retained for learning AND posterity.  Fun stuff.

 

EDIT:

For a really good read, the MyWord loader source is probably one of the more humorous.  M. Dodd really took things to a new level there, for Myarc code.  See code within spoiler tags.

 



 

* Dull, boring, ugly, uniteresting, title screen for MY-Word.
*  Written by the very essence of boredom, Mike Dodd, who, instead of
*  writing anything worthwhile for MYARC, spends his time writing
*  deadly-dull title screens as a part of the evil Lord Jack Riley's
*  sinister plot to wipe out all creativity in the world.
*      DEF  MWT          Have to have some sort of name
*      REF  VMBW,VSBW,VMBR
VWA    EQU  >8C02        In 99/4A Mode
VWD    EQU  >8C00
VWRD   EQU  >8C06
CHRBUF EQU  >E000
*CHRBUF BSS  768          Space to stick characters I'm inverting
       EVEN
* Now for all sorts of dull, boring, character definitions
CHARD  DATA >0000,>7C7C,>7C7C,>7070   128
       DATA >0000,>FCFC,>FCFC,>0000   129
       DATA >0000,>0080,>C0E0,>0000   130
       DATA >7070,>7070,>7070,>7070   131
       DATA >3010,>0C00,>0004,>0C1C   132
       DATA >3C7C,>7C7C,>7870,>6040   133
       DATA >0000,>FC7C,>FCFC,>F8F0   134
       DATA >E0C0,>8000,>0000,>0000   135
       DATA >0000,>E0C0,>8000,>0000   136
       DATA >FCFC,>FCFC,>0000,>0000   137
       DATA >0000,>0000,>0000,>00FC   138
       DATA >8080,>8080,>8080,>8080   139
       DATA >0000,>0000,>0000,>0080   140
       DATA >8080,>8080,>8080,>80FC   141
* MYARC LOGO IS LAID OUT LIKE THIS:
*
* 128 129 129 129 129 129 130
* 131   M   Y   A   R   C
* 132 134 136
* 133 135


* Here comes the deadly dull screen data (yawn):
* The format for this boring data table is as follows:
* BYTE MSBy screen addr,LSBy screen addr,# bytes,data
* If it hits a byte >FF, it changes the character offset from 00 to 80,
*  or 80 to 00. Used for inverting characters.
* If hits an >FF,>FF, it stops
*  First, draw MYARC logo
SCRND  BYTE >00,>D8
       BYTE 7,128,129,129,129,129,129,130
       BYTE >01,>00
       BYTE 6,131,'M','Y','A','R','C'
       BYTE >01,>28
       BYTE 3,132,134,136
       BYTE >01,>50
       BYTE 2,133,135
* Now for some real, honest text:
       BYTE >01,>F0,7
       TEXT 'MY-Word'
       BYTE >02,>41,5
       TEXT 'V1.22'      Try to guess!       UPDATE
       BYTE >03,>5F,1,>8C     1 dot over the "G" (loadinG) for pixel col after
       BYTE >03,>89,1,>8C     1 dot over the "T" (waiT) for pixel col after
       BYTE >FF          Start writing typical, dull, inverse characters
       BYTE >03,>80,8
       TEXT 'Loading'
       BYTE 141-128      Very thin vertical line&botoom line - offset
       BYTE >03,>A6,12
       TEXT 'Please Wait'
       BYTE 139-128      Very thin vertial line - offset
       BYTE >FF,>FF      All done. Let's stop this garbage
       EVEN
TITLE
*      MOV  R11,@TITRT        jph lives
       LIMI 0
*MWT    LIMI 0            Kill interrupts so VDP doesn't get screwed. On
*                        second though, if the screen was really messed
*                        up, maybe it would be more interesting. Hmmmm.
       LI   R0,>900      Point to where I sincerly hope char data is.
       LI   R1,CHRBUF    CPU buffer
       LI   R2,768       A lot
       BLWP @VMBR        Read it
INV    INV  *R1+         Invert the stupid thing
       DECT R2           Are we done????
       JNE  INV          NO (groan. 766 to go - or less)
       LI   R0,>D00      Starting with char 160 (128 + 32)
       LI   R1,CHRBUF    Start of inverted char set
       LI   R2,768       A whole lot
       BLWP @VMBW        Write it
       BL   @VRSET       Set two incredible VDP registers
       BYTE 0,2,>00,>50  Text, and hope like crazy that rest is set up.
       BL   @VRSET       Wait... is the boring MDD going to write another?
       BYTE 7,1,>F4      Yes... ONE INCREDIBLE REGISTER!!! The colors!!
       BL   @VFILL       Lets fill
       DATA 0,>2000,960  Next time I'll try >2A (*), just to be different
*                        P.S. - >2A looked ugly
       LI   R0,>C00      Char 128. Force of habit
       LI   R1,CHARD     Point to boring character data
*                        (interesting char data not present in this version)
       LI   R2,112       Not a lot
       BLWP @VMBW        Write (Writing is more fun than reading, anyway)
       BL   @VFILL       Lets fill the sucker again
       DATA 40,>8900,40  R1 C0 - thick line all the way across
       BL   @VFILL       Not again!?!?
       DATA 800,>8A00,40 R20 C0 - thin line across
       BL   @VFILL       What, another fill??
       DATA 856,>8A00,7  Yes, afraid so - a VERY thin line (VTL) over LOADING
       BL   @VFILL       I can't be serious - ANOTHER FILL?????!!!!!????
       DATA 894,>8A00,11 I'm deadly serioud - a VTL over PLEASE WAIT
       LI   R1,>8C00     Yeeaaahhh.. we're done filling!!!!!!
       LI   R9,SCRND     Point to start of screen data. Better than char data!
       SETO R10          End flag
       CLR  R8           Offset = >00
MWT1   CB   *R9,R10      A special flag?
       JEQ  MWT3         Yes (in a reverent tone of voice)
       MOVB @1(R9),@VWA  No (in a degrading tone of voice)
       MOVB *R9+,R0      Get MSBy of address
       ORI  R0,>4000     I'm writing (I LOVE to write!!)
       MOVB R0,@VWA      Write to VDP chip
       INC  R9           Get over LSBy
       MOVB *R9+,R0      Get length
       SRL  R0,8         shift down
MWT2   MOVB *R9+,R1      Get char
       AB   R8,R1        Add offset
       MOVB R1,@VWD      Write to VDP (don't you just LOVE all these writes!)
       DEC  R0           Done? (enough questions - let's have some statements!)
       JNE  MWT2         No (now THAT'S a statement, not a wimpy question!!)
       JMP  MWT1         Get next data block
* The following section handles special flags. It is only to be talked about
* in a reverent, worshipful, tone of voice. Hint: take tone of voice you use
* to talk about Jack Riley. That is a perfect example of the tone NOT to use
* in reference to this section. (Wasn't that helpful?)
* The reason for the holiness of this area is that this is the area that Lord
* Riley wanted put in. Since His Lordship is such an important person, it only
* follows that it should be mentioned in a reverent tone.
* (What we have here is your basic contradiction in terms - Riley and Important)


MWT3   CB   @1(R9),R10   Is it (remeber... reverence is the key) the end flag?
       JEQ  MWT4         Yes, your worship, it is (Now THAT's more like it!)
       AI   R8,>8000     Change offset
       INC  R9           Point to next data cluster
       JMP  MWT1         Get another block
*MWT4   LIMI 2            Let C/A/D work
*      JMP  $            Complete lock up!!!!!!!!
MWT4   B    @BEGIN1
*TITRT  EQU  $-2
*
* What follows are general-purpose routines. You do not have to reference them
* in a worshipful voice.
VRSET  MOVB *R11+,@VWA
       LI   R0,>9100
       MOVB R0,@VWA
       MOVB *R11+,R0
       SRL  R0,8
VRSET1 MOVB *R11+,@VWRD
       DEC  R0
       JNE  VRSET1
       INC  R11
       ANDI R11,>FFFE
       RT
SVDPWA LI   R2,>4000
       JMP  SVDPXA
SVDPRA CLR  R2
SVDPXA MOV  *R11+,R1
       MOVB R1,R0
       SRL  R0,6
       MOVB R0,@VWA
       LI   R0,>8E00
       MOVB R0,@VWA
       ANDI R1,>3FFF
       SWPB R1
       MOVB R1,@VWA
       SWPB R1
       SOCB R2,R1
       MOVB R1,@VWA
       RT
VFILL  MOV  *R11+,@VFILL1
       MOV  R11,@VFILL2
       BL   @SVDPWA
VFILL1 DATA >0000
VFILL2 EQU  $+2
       LI   R11,>0000
       MOV  *R11+,R0
       MOV  *R11+,R1
VFILL3 MOVB R0,@VWD
       DEC  R1
       JNE  VFILL3
       MOVB R1,@VWA
       LI   R0,>0E00
       MOVB R0,@VWA
       RT
* Finally! An end to this stupid program!!!
*      END  MWT


 

  • Haha 6

Share this post


Link to post
Share on other sites
1 hour ago, InsaneMultitasker said:

All comments are retained for learning AND posterity.  Fun stuff.

 

EDIT:

For a really good read, the MyWord loader source is probably one of the more humorous.  M. Dodd really took things to a new level there, for Myarc code.  See code within spoiler tags.

 

 

 

That is the funniest code I've ever read.

 

I'm going to think of this every time I write a loop:

 

       LI   R2,768       A lot
       BLWP @VMBR        Read it
INV    INV  *R1+         Invert the stupid thing
       DECT R2           Are we done????
       JNE  INV          NO (groan. 766 to go - or less)

 

  • Like 2

Share this post


Link to post
Share on other sites

Anyway, back to development, here's a brief update to round out the weekend: 

 

1. Modified new TIMODE2 command (which frees up 64K allocated to MyWord via TIMODE) memory allocation routine

2. Implemented TIPI mapped drives DSK1,2,3,4.  All opcodes available via Geneve OS.   Level 2 for /4A mode is partially implemented.

3. Updated REMAP command for TIPI mapped drive usage.  Letters W,X,Y,Z correspond to TIPI drives DSK1,2,3,4.  Redirection to drives other than 1-4 is pending finalization of the level 2 IO.

4. DIR command modified to allow TIPI mapped drives.  COPY command is pending further review.

5. Completed review of SCSI routine memory usage; hard-coded memory pages have been corrected to use defined EQUates to allow for future changes.

 

  • Like 5

Share this post


Link to post
Share on other sites

Ran across a disk with the following two files related to the OS encryption process.  Long ago, probably during the GEnie online service period, I had asked JJ some questions regarding MDOS programming.  I was trying to figure out how to write native OS programs. He sent me some notes (the first spoiler) and the code to the ENCRYPT program (second spoiler).  I'm guessing this is from the very early 90s and while it may not be exactly how I write my own programs,  I still use his shared command line argument code and TTYOUT code to this day. :)

 



Tim,

I don't really have a good grip on mdos programs.  Most of the stuff is
just thrown together haphazardly and surprizingly runs!

The whole trick to writing programs that run from mdos is to use the xops
in the operating system for as much i/o, video work, etc. as possible.
Paul really did us a good job supplying us with a lot of useful routines.

The code included in this archive is for a program I wrote a few years
ago, called ENCRYPT.  It's the shortest code I have, and it's fairly
well commented.  There are i/o's for load/save, and unprotect, and a
memory reqest.   Realize that upon loading a program, mdos will allocate
enough pages for that program to reside in.  For instance, you write a
program that is 20k big.  It loads at >0400.  Mdos will allocate enough
8k pages to you automatically for the program to sit in.

If your program doesn't require any more memory than the memory it
occupies, then no further memory requests are required from mdos.

However, if you plan on using memory at the end of your program for
buffers, or whatever, you must request it.  If you want to establish an
8k buffer at >C000 for storing a hard disk track read for instance,
you'd ask mdos for one page using the memory xop.  Once you get that
page number, you'd write the byte to the mapper register for the
>C000 - >E000 area - place the byte returned from the mem XOP in >F116.
As a programmer, you don't really care what page was given to you.  If
you need two pages, one for track data read from winchester 1, and
the other a read from winchester 2, request 2 pages.  Save these two bytes
to locations in your program like W1PAGE and W2PAGE.  Now, when you want
to look at winchester 1 data at >C000, do a movb @w1page,@>f116.
To look at data in the w2page, just do a movb @w2page,@>f116.  The old
data in the w1page will not be destroyed, just mapped out of the
active 64k memory map.

So for a guy writing a word processor or disk copier that wants all the
memory available, just ask for it, then keep track of the bytes.

The mapper registers are hardware bytes that you can read or write to
from within your program.  Writing the byte >BA to >F110 would page the
actual DSRs from your pbox cards into the 64k memory at >0000 - >2000,
but would also crash mdos.

You can of course place any page into any memory map, but by not asking
mdos for the page number, you run the risk of destroying the mdos code,
or someone elses code or data if you are multitasking.

Hope this stuff helps,
jj

 

Source to Encrypt:



      UNL
*           ENCRYPT
*           John A. Johnson, 25 December 1988
*           encrypts or un-encrypts an mdos program
*
WS     EQU  >F000        my workspace
BUF    EQU  >2000        users program loads in here
BLKLEN EQU  BUF+2        length of program
ENTRY  EQU  BUF+4        entry address, ie. >0400
PROG   EQU  BUF+6        start of encrypted code
WORK   EQU  >E802        just a buffer for parsing etc
CODE   EQU  >A006        starting code word
MAXPRG EQU  >C000        largest program loadable
       DXOP CALL,0       define CALL as meaning XOP 0
*
       LWPI WS           use a fast workspace
       LI   R0,1         get memory pages
       LI   R1,7         i need 7 new pages to run this thing
       LI   R2,1         local page 1
       SETO R3           if I wanted slow ram, I'd run a C64
       CALL @MEM         request the ram from mdos
       ABS  R0           check for errors
       JEQ  GOTMEM       if none
       BL   @TTYOUT      else paint message
       DATA NOMEM,0      'not enough memory'
       B    @EXIT        then exit to mdos
*
GOTMEM LI   R0,4         get address map
       LI   R1,MAP       execution address of map
       LI   R2,10        map is 10 bytes big
       CALL @MEM         get the info from mdos
*
       LI   R1,MAP+1     now bank in the new ram pages
       MOVB *R1+,@>F111  new ram for >2000 - >3FFF
       MOV  *R1+,@>F112  new ram for >4000 - >7FFF
       MOV  *R1+,@>F114  new ram for >8000 - >BFFF
       MOV  *R1,@>F116   new ram for >C000 - >FFFF
*
       LI   R0,>2800          40 bytes for WORK length
       LI   R1,WORK-1         patch it
       MOVB R0,*R1+           crunch command line and move it to WORK
       MOV  @>0128,R2         get command line argument address
       JEQ  NOGOT             if no arguments
       CB   @2(R2),@-1(R1)    see if command line is too long
       JHE  NOGOT             if too long
       MOV  R1,R5             else save address of WORK to R5
       DEC  R5                to length pointer
       MOVB @2(R2),R6         argument length
       SRL  R6,8              make it a word
       INCT R6                add two
NXTNOD MOV  R2,R3             save command address
       INCT R3                add 2
       MOV  R2,R4
       AI   R4,8
GETNOD MOVB *R3+,*R5+         start moving the data
       DEC  R6                till count is done
       JEQ  GOTCMD
       C    R3,R4             r3 holds node count
       JL   GETNOD            if done this node, go get some more
       MOV  *R2,R2            get next node
       JMP  NXTNOD
*
GOTCMD MOVB @WORK-1,R1   length of argument
       JEQ  NOGOT        if no arg
       SRL  R1,8         else make it a word
       INC  R1           and add 1 for the loop conter
       LI   R2,40        largest filename possible
       LI   R4,WORK      address of command line text
GETFIL CB   *R4+,@H32    look for a space in the command line (filename)
       JLE  GOTFIL       if ASCII 0-32, we have the filename
       DEC  R1           don't have it yet, count down
       JEQ  NOGOT        we done with arguments?
       DEC  R2           we done with the 40 possible bytes of filename?
       JNE  GETFIL
NOGOT  BL   @TTYOUT      yep, bad argument, paint help info
       DATA CRLF,0       with a CRLF first for neatness
       B    @EXIT        then exit program
*
GOTFIL CLR  R0           we have the filename, now put a null at end
       DEC  R4           back to the previous byte
       MOVB R0,*R4       then write a null
       LI   R0,8         parse the filename
       LI   R1,WORK      get logical filename from here
       LI   R2,LEN+1     and put hardware name in the pab
       CLR  R3           what the hell is an alias prefix?
       CALL @UTIL        go do the parse
*
* load the program into memory
*
       BL   @TTYOUT      put 'Loading' message up
       DATA LDING,0
       LI   R0,FILE      go ahead and load in the encrypted program
       CALL @IO          do the load
       MOVB @FILE+2,R1   see what the error byte looks like
       JEQ  OKFILE       if it's not 0, post error
       B    @ERROR
*
OKFILE CLR  @DOCRPT      flag - if low, then encrypt
       MOV  @ENTRY,R2    put entry address of block in R2, ie >0400
       MOV  R2,R3        save it for comparison later
       ANDI R2,>FFFE     make it an even load address
       C    R2,R3        compare it to the original
       JNE  UNCRPT       if it's encrypted
       ORI  R2,>0001     make it an odd address
       SETO @DOCRPT      show an encryption about to happen
UNCRPT MOV  R2,@ENTRY    put it back as an even or odd word
       ABS  @DOCRPT      encrypting?
       JEQ  CRPT1        if no, go un-encrypt it
       BL   @TTYOUT      DOCRPT is hi, paint 'encrypting' message
       DATA DOCR,0
       BL   @TTYOUT      now print 'program'
       DATA H32,0
       JMP  CRPT2        then go encrypt
CRPT1  BL   @TTYOUT      DOCRPT is low, paint 'un-encrypting' message
       DATA UNCR,0
*
CRPT2  MOV  @BLKLEN,R3   now get the programs length
       ANDI R3,>FFFE     make it even for the count routine and DECT
       LI   R4,CODE      starting code word
       LI   R2,PROG      6th byte of the program
       ABS  @DOCRPT      are we encrypting?
       JNE  CRYPT        if so, goto crypt routine
*
***********************************
* this code un-encrypts a program *
***********************************
*
DECODE MOV  *R2,R5       fetch the first instruction of the program
       INV  R5           flip the bits
       SRC  R5,11        shift them around a little
       XOR  R4,R5        exclusive or with the code word - >A006 to start
       MOV  R5,*R2+      write it back out to memory
       INCT R4           increment the code word
       DECT R3           bytes remaining in program to convert
       JOC  DECODE       if we aren't done converting
       JMP  SAVPRG       else go save converted program
*
********************************
* this code encrypts a program *
********************************
*
CRYPT  MOV  *R2,R5       fetch the first instruction
       XOR  R4,R5        xor with the starting code word - >A006
       SRC  R5,5         shift them around
       INV  R5           flip em
       MOV  R5,*R2+      and write it back to the program
       INCT R4           increment the code word
       DECT R3           started with total program size
       JOC  CRYPT        are we done encrypting this program?
*
* job done, overwrite original program with converted program
*
SAVPRG BL   @TTYOUT         show 'saving' message
       DATA SVING,0
       MOVB @VIDEO+1,@FILE  turn pab into a SAVE
       MOV  @BLKLEN,R0      get the block length
       AI   R0,6            and include the 6 byte header
       MOV  R0,@LEN-2       patch pab with number of bytes to save
       LI   R0,FILE         and save the file back to disk
       CALL @IO             do the save
       MOVB @FILE+2,R1      then check for errors
       JEQ  EXIT            if none
       SRL  R1,13           get the error as a word
       CI   R1,1            is it a 1?
       JNE  ERROR           if it was something besides protected
       BL   @TTYOUT         else paint protected message
       DATA PROT,0
*
GETKEY LI   R0,3            keymode 3 for uppercase returns
       CALL @KEY            go get a key from user
       JNE  GETKEY          if no key is pressed
       ANDI R1,>7F00        else strip the hi bit
       CB   R1,@NO          and see if it's a N
       JNE  NOTN            if it isn't, check for a Y
       BL   @TTYOUT         else write to screen...
       DATA NO,4            ...the No
       BL   @TTYOUT
       DATA ABORT+2,0       and the abort message
       JMP  EXIT            then exit
NOTN   CB   R1,@YES         now see if a Y was pressed
       JNE  GETKEY          if not, go get another key
       BL   @TTYOUT         else print to the screen...
       DATA YES,5           the Yes, and prepare to unprotect
*
       LI   R0,FILE         pab address
       LI   R1,>000C        protect/unprotect opcode
       MOVB R1,@FILE+2      show unprotect about to happen
       SWPB R1              now write 0C to the opcode
       MOVB R1,*R0          patch the pab
       CALL @IO             and do the unprotecting
       JMP  SAVPRG          then go save again
*
ERROR  BL   @TTYOUT         if we get an i/o error, tell the user
       DATA IOERR,11        with an i/o error message
       BL   @TTYOUT         now print 'task aborted' message
       DATA ABORT,0
EXIT   BL   @TTYOUT         normal exit
       DATA CRLF,2          with a CRLF
       BLWP @0              then back to mdos
*
* MDOS write tty routine
*
TTYOUT MOV  *R11+,R8     get data address
       MOV  *R11+,R9     get length of data to write
       MOV  R9,R2        save length in r2 for the ttyout routine
       LI   R10,WORK     for the move to hi memory
       MOV  R10,R1       save for the ttyout routine
TTY1   MOVB *R8+,*R10+   move em to hi memory
       JEQ  TTY2         if we hit a null
       DEC  R9           till r3 is zero
       JNE  TTY1
TTY2   LI   R0,>0027     do the actual ttyout routine
       CALL @VIDEO
       B    *R11
*
* end of code, data follows
*
KEY    DATA 5
VIDEO  DATA 6            video xop
MEM    DATA 7            memory manager xop
IO     DATA 8            i/o xop
UTIL   DATA 9            utility xop
*
NO     TEXT 'No'
       BYTE 13,10
YES    TEXT 'Yes'
CRLF   BYTE 13,10
       TEXT 'ENCRYPT v1.1, John A. Johnson, 1 Jan 89'
       BYTE 13,10,10,9
       TEXT ' Usage: ENCRYPT target-program'
       BYTE 13,10,10,9,9
       TEXT 'ENCRYPT will encrypt an MDOS program'
       BYTE 13,10,9,9
       TEXT 'or un-encrypt an encrypted program.'
       BYTE 10,0
PROT   BYTE 13,10
       TEXT 'File is protected, overwrite? '
       BYTE 0
IOERR  BYTE 13,10
       TEXT 'i/o error'
LDING  TEXT 'Loading program'
       BYTE 13,10,0
DOCR   TEXT 'Encrypting'
       BYTE 0
UNCR   TEXT 'Un-encrypting'
H32    TEXT ' program'
       BYTE 13,10,0
SVING  TEXT 'Saving converted program'
       BYTE 13,10,0
NOMEM  TEXT 'Insufficient memory'
ABORT  TEXT ', task aborted'
       BYTE 13,10,0
*
* pab used to load target program, max program size = 48k (190+ sectors)
*
FILE   DATA >0500,0,BUF,0,0,0,MAXPRG
LEN    DATA >0028
FNAME  EQU  $
MAP    EQU  FNAME+40
DOCRPT EQU  MAP+10
       END


 

 

  • Like 5

Share this post


Link to post
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.

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...