Sinclair zx80 / ​​zx81 emulation

image

Many will agree that the emerging COVID-19 pandemic has pretty much ruined the life of the IT community. But we will not talk about a dark strip, but about another episode.

Already in March, the famous demoparty Forever 2020 was canceled , and later the event was postponed to autumn. Long before the cancellation, I spoke with the organizers. They refused to accept one of my work, explaining that there is no Apple II, and in return asked for a video of work from a real computer.

Well, I could not get the record, so I noticed the list of platforms:
Amstrad CPC, Thomson, PMD-85, MSX, ZX81, Sam Coupe, all non-C = 64 8-bit Commodores or any other 8-bit system

I was attracted to the ZX81, as I was already trying to learn the computer, but crashed.

Research went according to my usual pattern:

Emulator


I chose EightyOne
took version 1.6.1. The version has a convenient debugger, but the program does not emulate another model - ZX80, later I found another build 3.7.

Cross means


The search brought to FASM (a topic on the forum adapted for the platform. However, the compiled examples did not start. I tried other assembler options - Pasmo and others, but did not compile a working program.

Long searches brought an example of printing Hello, world!

, miracle! it turned out! Now the turn has come to the third episode.

Documentation


Part of the information was found here.
Disassembler ROM here.

Memory card:

0000-1FFF - ROM
2000-3FFF - Shadow ROM.   ,   Interface 1
4000-7FFF -  16

Part of the memory is reserved for system variables .

Further, at 16509, the BASIC program and its variables are stored.

The program on BASIC contains the format:

2      big endian
2   
...  
1  ($76) -  

For a cassette, only BASIC programs are possible; this method was proposed:

1 REM (    )
2 RANDOMIZE USR(16514) -    ,   REM

You should pay attention to the system variable D_FILE, which indicates the video memory.

In the indicated example, this is implemented as follows:

D_FILE:     defw    display_file

display_file:   defb    _NL
        defs    32
...
        defs    32
        defb    _NL

The first byte is a sign of the beginning of the line, then 32 bytes are spaces.

It turned out 24 lines, which looked bulky.

The first program I wrote:

image

;compile with sjasmplus
	device zxspectrum128

p_start:    org 0x4009
begin

VERSN:      defb    0
E_PPC:      defw    20      ; BASIC line number of line with cursor.
D_FILE:     defw    display_file2
DF_CC:      defw    display_file2+1
VARS:       defw    variables
DEST:       defw    0
E_LINE:     defw    edit_line
CH_ADD:     defw    p_end-1
X_PTR:      defw    0
STKBOT:     defw    p_end
STKEND:     defw    p_end
BERG:       defb    0
MEM:        defw    MEMBOT
SPARE1:     defb    0
DF_SZ:      defb    2       ; Number of lines in lower part of screen.
S_TOP:      defw    10      ; BASIC line number of line at top of screen.
LAST_K:     defw    0xffff
DB_ST:      defb    0
MARGIN:     defb    55      ; Blank lines above/below TV picture: US = 31, UK = 55.
NXTLIN:     defw    display_file    ; Memory address of next program line to be executed.
OLDPPC:     defw    0
FLAGX:      defb    0
STRLEN:     defw    0
T_ADDR:     defw    0x0c8d
SEED:       defw    0
FRAMES:     defw    0       ; Updated once for every TV frame displayed.
COORDS:     defw    0
PR_CC:      defb    0xbc
S_POSN:     defb    0x21,0x18
CDFLAG:     defb    0x40
PRBUF:      defs    0x20
        defb    _NL
MEMBOT:     defs    0x1e
SPARE2:     defw    0

; Start of the BASIC area for user programs.

basic_0001: defb    0,1     ; 1 REM
        defw    basic_0010-basic_0001-4
        defb    _REM

; Start of user machine code program
mem_16514:
	ld hl,p_end;display_file2
	push hl
;cls
	ld c,25
c1:
	ld b,32
	ld (hl),$76:inc hl
c2:
	ld (hl),0:inc hl
	djnz c2
	dec c
	jr nz,c1

	pop hl
	push hl
	ld c,$0
ylp:
	ld (hl),$76
	inc hl
	ld b,32
xlp:
	ld (hl),c
	inc hl
	inc c

	bit 6,c
	jr nz,endp;ret nz
	djnz xlp
	jr ylp
endp:
	pop hl
	ld (D_FILE),hl
	jr $
display_file2:
 dup 25
 defb _NL
 edup


end
	display /d,end-begin
	savebin "prb.p",begin,end-begin

A shortened version suggested this topic .

One drawback: after loading the program, the bottom line is not displayed. This is not surprising, because the lines are empty. Reading the manuals suggested another change:

NXTLIN:     defw    basic_0010 ;    

It turned out such a simple trick: after loading, you do not need to type RUN, the program will start by itself.

In short, I will describe the essence of the program: first filling in the video memory according to the model, as it was in the printing program β€œHello, world”, then filling the lines with characters with codes 00-63.

image

At the first development, I made a mistake and wrote filling characters with codes 00-255, but the program did not work, as part of the codes are not used.
The result of research was the work of kerr , which would seem uninteresting, but for me the program itself is a great achievement.

And before the demoparty, there is a lot of time that will be spent on developing a program in the 1k nomination.

Remains ZX80.

There is a different order of system variables for it.

Software is stored here .

Therefore, I typed the program and looked in the debugger:

image

There is a slight limitation here - 1k memory, so you need to think about which program to write.

Maybe I'll write someday.

All Articles