I have rebuilt my original cross assembler file I had on ts1000.us using an original from Zeddy-br and cleaned it up and added a lot of comments. This makes it very easy to create self running machine language programs for the TS1000 (ZX81).

; ZX81CRSS.ASM
;
; This file will allow you to compile z80 code directly to a .P file that
; can be loaded into one of the various ZX81 / TS 1000 emulators. To use
; add your code wher it says "Put your code here", compile and load.
;
; To compile use the Telemark assembler:
;
; TASM -b -80 zx81crss.asm zx81crss.p
;
; William Hicks
;
; Recreated in 03/2018 from code written by Zeddy-Br in 08/2005
.org 16393
VERSN .db 0 ; 0 Identifies ZX81 BASIC in saved programs
E_PPC .dw 0 ; Number of current line (with program cursor)
D_FILE .dw R_DFILE ; Address of Display File (screen data) in memory
DF_CC .dw R_DFILE + 1 ; Address of PRINT position in display file
; Can be poked so that PRINT output is sent elsewhere
VARS .dw R_VARS ; Address of user program variables in memory
DEST .dw 0 ; Address of variable in assignment
E_LINE .dw R_E_LINE ; Address of line being editted in memory
CH_ADD .dw R_LAST - 1 ; Address of the next character to be interpreted:
; the character after the argument of PEEK, or the
; NEWLINE at the end of a POKE statement
X_PTR .dw 0 ; Address of the character preceding the [S] marker
STKBOT .dw R_STKBOT ; Address of the Calculator stack in memory.
; This is where Basic does the math calculations
STKEND .dw R_STKBOT ; End of the Calculator stack
BERG .db 0 ; Calculator's b register
MEM .dw MEMBOT ; Address of area used for calculator's memory.
; (Usually MEMBOT, but not always.)
.db 0 ; Not Used
DF_SZ .db 2 ; The number of lines (including one blank line)
; in the lower part of the screen.
S_TOP .dw 1 ; The number of the top program line in automatic listings
LAST_K .db 0ffh,0ffh ; Shows which keys pressed
.db 0ffh ; Debounce status of the keyboard
MARGIN .db 55 ; Number of blank lines above or below picture:
; 55 in Britain, 31 in America
; Make NXTLIN equal Line_10 if you want the code to autorun,
; or make it equal R_DFILE if you do not want it to autorun
NXTLIN .dw Line_10 ; Address of next program line to be executed
OLDPPC .dw 0 ; Line number of which CONT jumps
FLAGX .db 0 ; Various flags
STRLEN .dw 0 ; Length of string type destination in assignment
T_ADDR .dw 0c8dh ; Address of next item in syntax table (very unlikely to be useful)
SEED .dw 0 ; The seed for RND. This is the variable that is set by RAND
FRAMES .dw 0ffffh ; Counts the frames displayed on the television.
; Bit 15 is 1. Bits 0 to 14 are decremented for each frame
; set to the television. This can be used for timing, but
; PAUSE also uses it. PAUSE resets to 0 bit 15, & puts in
; bits 0 to 14 the length of the pause. When these have been
; counted down to zero, the pause stops. If the pause stops
; because of a key depression, bit 15 is set to 1 again.
COORDS .db 0 ; x-coordinate of last point PLOTted
.db 0 ; y-coordinate of last point PLOTted
PR_CC .db 0bch ; Less significant byte of address of next position for
; LPRINT to print as (in PRBUFF)
S_POSN .db 33 ; Column number for PRINT position
.db 24 ; Line number for PRINT position
CDFLAG .db 01000000b ; Various flags. Bit 7 is on (1) during compute & display mode
PRBUFF .fill 33,0 ; Printer buffer
MEMBOT .fill 30,0 ; Calculator's memory area; used to store numbers that cannot
; conveniently be put on the calculator stack
.dw 0 ; Not Used
Line_0:
.db 0,0 ; line number
.dw Line_10 - $ - 2 ; line length
.db 0eah ; REM
; *********************************
; Put your code here. Do not use
; the Z80 HALT instruction as the
; ZX81 will see it as a NEWLINE
; and it could cause your program
; crash (maybe).
; *********************************
ret
; *********************************
; Do not change anything after this
; *********************************
.db 076h ; NEWLINE
Line_10:
.db 0,10 ; line number
.dw R_DFILE - $ - 2 ; line length
.db 0f9h ; RAND
.db 0d4h ; USR
.db 01dh ; 1
.db 022h ; 6
.db 021h ; 5
.db 01dh ; 1
.db 020h ; 4
.db 07eh ; FP mark
.db 08fh ; 5 bytes FP number
.db 001h ;
.db 004h ;
.db 000h ;
.db 000h ;
.db 076h ; NEWLINE
R_DFILE .fill 25,076h ; Compacted D_FILE (25 NEWLINE's)
R_VARS
.db 080h ; End of Variables Marker
R_E_LINE
R_STKBOT
R_LAST
.end

I wonder if it will be possible to put the 10 line (RAND USR) in the printer buffer, and assign the NXT_line to the prt buffer!

Fill a mirrored DF_File next, and jump to you ASM after the Dfile.

But, the basic will crash on the RET function...
It can allow a full memory asm code (after the PRTbuffer) on a single file, and save room in the basic/vars location.
Anyone test this attic code structure?

I think Dr. Beep is quite brutal in his use of all the free memory locations, it's not something I've tried though. But perhaps in this case that's missing the point - this is supposed to be a nice easily understood starter project for people