"Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
palmheads
Posts: 40
Joined: Thu Apr 30, 2009 8:15 am

"Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by palmheads »

Hi

Over christmas thought I would get back into learning ZX81 assembly language and machine code. Am using Linux as my desktop, so am also using http://sz81.sourceforge.net/

Thought I would use the excellent updated version of Mastering Machine Code on the ZX81. Using an example from http://www.users.waitrose.com/~thunor// ... ter07.html

I was able to follow the updated book & using chapter07-hexld2.p I was able to get working a HELLO WORLD example seen below.

Code: Select all

OLD ROM   NEW ROM
E1        E1        SPRINT    POP HL
7E        7E                  LD A,(HL)
23        23                  INC HL
E5        E5                  PUSH HL
FEFF      FEFF                CP FF
C8        C8                  RET Z
F5                            PUSH AF       <- OLD ROM ONLY
CDE006                        CALL PRPOS    <- OLD ROM ONLY
F1                            POP AF        <- OLD ROM ONLY
CD2007    CD0808              CALL PRINT
18EF      18F4                JR SPRINT
CD2B40    CD8240               CALL SPRINT
;OH WHAT A BEAUTIFUL MORNING;  DEFM "HELLO WORLD"
FF        FF                   DEFB FF
C9        C9                   RET

Using this example from the book, thought it would be cool to try & get it working with pasmo. Here is my go at it using the mctemplate that comes with sz81

Code: Select all

; mctemplate - a Sinclair ZX81 machine code template
; Copyright (C) 2010 Thunor <thunorsif_at_hotmail.com>
; 
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
; 
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
; 
; You should have received a copy of the GNU General Public License
; along with this program.  If not, see <http://www.gnu.org/licenses/>.

; =====================================================================
; mctemplate 0.1.3
; 
; Tabs are set to 8.
; 
; See mctemplate.txt for assembling instructions and information.
; =====================================================================

; Sinclair character codes.

_SPC        equ 0x00        ; " "
_DQT        equ 0x0b        ; "
_PND        equ 0x0c        ; £
_DLR        equ 0x0d        ; $
_CLN        equ 0x0e        ; :
_QMK        equ 0x0f        ; ?
_OBR        equ 0x10        ; (
_CBR        equ 0x11        ; )
_GTH        equ 0x12        ; >
_LTH        equ 0x13        ; <
_EQU        equ 0x14        ; =
_PLS        equ 0x15        ; +
_MNS        equ 0x16        ; -
_ASK        equ 0x17        ; *
_SLS        equ 0x18        ; /
_SMC        equ 0x19        ; ;
_CMA        equ 0x1a        ; ,
_FST        equ 0x1b        ; .
_0      equ 0x1c
_1      equ 0x1d
_2      equ 0x1e
_3      equ 0x1f
_4      equ 0x20
_5      equ 0x21
_6      equ 0x22
_7      equ 0x23
_8      equ 0x24
_9      equ 0x25
_A      equ 0x26
_B      equ 0x27
_C      equ 0x28
_D      equ 0x29
_E      equ 0x2a
_F      equ 0x2b
_G      equ 0x2c
_H      equ 0x2d
_I      equ 0x2e
_J      equ 0x2f
_K      equ 0x30
_L      equ 0x31
_M      equ 0x32
_N      equ 0x33
_O      equ 0x34
_P      equ 0x35
_Q      equ 0x36
_R      equ 0x37
_S      equ 0x38
_T      equ 0x39
_U      equ 0x3a
_V      equ 0x3b
_W      equ 0x3c
_X      equ 0x3d
_Y      equ 0x3e
_Z      equ 0x3f

; Inverse equivalents of the above.

_SPCV       equ _SPC+0x80   ; [ ]
_DQTV       equ _DQT+0x80   ; ["]
_PNDV       equ _PND+0x80   ; [£]
_DLRV       equ _DLR+0x80   ; [$]
_CLNV       equ _CLN+0x80   ; [:]
_QMKV       equ _QMK+0x80   ; [?]
_OBRV       equ _OBR+0x80   ; [(]
_CBRV       equ _CBR+0x80   ; [)]
_GTHV       equ _GTH+0x80   ; [>]
_LTHV       equ _LTH+0x80   ; [<]
_EQUV       equ _EQU+0x80   ; [=]
_PLSV       equ _PLS+0x80   ; [+]
_MNSV       equ _MNS+0x80   ; [-]
_ASKV       equ _ASK+0x80   ; [*]
_SLSV       equ _SLS+0x80   ; [/]
_SMCV       equ _SMC+0x80   ; [;]
_CMAV       equ _CMA+0x80   ; [,]
_FSTV       equ _FST+0x80   ; [.]
_0V     equ _0+0x80
_1V     equ _1+0x80
_2V     equ _2+0x80
_3V     equ _3+0x80
_4V     equ _4+0x80
_5V     equ _5+0x80
_6V     equ _6+0x80
_7V     equ _7+0x80
_8V     equ _8+0x80
_9V     equ _9+0x80
_AV     equ _A+0x80
_BV     equ _B+0x80
_CV     equ _C+0x80
_DV     equ _D+0x80
_EV     equ _E+0x80
_FV     equ _F+0x80
_GV     equ _G+0x80
_HV     equ _H+0x80
_IV     equ _I+0x80
_JV     equ _J+0x80
_KV     equ _K+0x80
_LV     equ _L+0x80
_MV     equ _M+0x80
_NV     equ _N+0x80
_OV     equ _O+0x80
_PV     equ _P+0x80
_QV     equ _Q+0x80
_RV     equ _R+0x80
_SV     equ _S+0x80
_TV     equ _T+0x80
_UV     equ _U+0x80
_VV     equ _V+0x80
_WV     equ _W+0x80
_XV     equ _X+0x80
_YV     equ _Y+0x80
_ZV     equ _Z+0x80

_NL     equ 0x76

_VAL        equ 0xc5
_INT        equ 0xcf
_USR        equ 0xd4
_NOT        equ 0xd7
_PWR        equ 0xd8        ; **
_THEN       equ 0xde
_STOP       equ 0xe3
_REM        equ 0xea
_LET        equ 0xf1
_PRINT      equ 0xf5
_RUN        equ 0xf7
_SAVE       equ 0xf8
_RAND       equ 0xf9
_IF     equ 0xfa

; RST routines (a selection of).

ERROR       equ 0x08        ; Follow with a byte error code -1.
PRINT_CHAR  equ 0x10        ; regA contains the char.

; ROM routines (a selection of).

KEYB_SCAN   equ 0x02bb
KEYB_DECODE equ 0x07bd

; Start of the system variables area.

ERR_NR      equ 0x4000
FLAGS       equ 0x4001
ERR_SP      equ 0x4002
RAMTOP      equ 0x4004
MODE        equ 0x4006
PPC     equ 0x4007

p_start:    org 0x4009

VERSN:      defb    0
E_PPC:      defw    20      ; BASIC line number of line with cursor.
D_FILE:     defw    display_file
DF_CC:      defw    display_file+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:  
;START   ld a,_ASK
;        call PRINT_CHAR
;        jr START
SPRINT  POP HL
        LD A,(HL)
        INC HL
        PUSH HL
        CP $FF
        RET Z       
        CALL PRINT_CHAR
        JR SPRINT
        CALL SPRINT

;        DEFM _O,_H,_SPC,_W,_H,_A,_T,_SPC,_A,_SPC,_B,_E,_A,_U,_T,_I,_F,_U,_L,_SPC,_M,_O,_R,_N,_I,_N,_G
        DEFM _H,_E,_L,_L,_O,_SPC,_W,_O,_R,_L,_D
        DEFB $FF
        RET

; End of user machine code program ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        defb    _NL
basic_0010: defb    0,10        ; 10 RAND VAL "USR 16514"
        defw    basic_0020-basic_0010-4
        defb    _RAND,_VAL,_DQT,_USR,_1,_6,_5,_1,_4,_DQT
        defb    _NL
basic_0020: defb    0,20        ; 20 REM ** TYPE RUN **
        defw    basic_end-basic_0020-4
        defb    _REM,_PWR,_SPC,_T,_Y,_P,_E,_RUN,_PWR
        defb    _NL
basic_end:

; Start of the display file (synonymous with video memory).

; Compressed for <= 3k RAM.

;display_file:  defb    _NL
;       defb    _NL,_NL,_NL,_NL,_NL,_NL,_NL,_NL
;       defb    _NL,_NL,_NL,_NL,_NL,_NL,_NL,_NL
;       defb    _NL,_NL,_NL,_NL,_NL,_NL,_NL,_NL

; Expanded for > 3k RAM.

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

; Start of the variables area used by BASIC.

variables:  defb    0x80

; Start of the edit line used by BASIC.

edit_line:

p_end:      end

If you save the above code as helloworld.asm, you can run pasmo like thus:

Code: Select all

pasmo -v helloworld.asm helloworld.p
Then you can open into your favourite emulator & run it with

Code: Select all

RAND USR 16526 
Then I thought I would try & get it working with ZX Assembler 2. So using this excellent version of the updated ZX Assembler manual here:
http://edu.i-lo.tarnow.pl/inf/retro/005 ... o/0005.php
and screenshots of the original manual here:
http://www.zx81stuff.org.uk/zx81/info.p ... .Cover.jpg

I got it working with only minor modifications. Go into EDIT mode & enter thus. Labels are limited to 5 chars. And I call the PRINT subroutine in the ROM directly (CALL 0808).

Code: Select all

SPRNT POP HL
           LD A,(HL)
           INC HL
           PUSH HL
           CP FF
           RET Z
           CALL 0808
           JR SPRNT
           CALL SPRNT
           DEFM "HELLO WORLD"
           DEFB FF
Press SHIFT Q to get back to the menu, then RUN from 4090. You should see HELLO WORLD.

I did all this to give me some confidence that what I was reading from one source, I could then transfer knowledge to the various ways of writing ZX81 assembly. Hope others who are struggling through it all (like me) can also learn & apply.

cheers
Daryn
sirmorris
Posts: 2811
Joined: Thu May 08, 2008 5:45 pm

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by sirmorris »

Hi Daryn!

For your next step down the tech history route you could try writing the code out on paper and then have assembling it using the mnemonic translation chart at the back of the ZX81 manual..! Of course you'll also need a relative jump calculator - a hastily scribbled 16x16 matrix should do it ;-)

Seriously though - it's amazing how many different ways there are too get machine code into an '81 :-D
Rink
Posts: 165
Joined: Wed Jun 27, 2012 5:48 pm

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by Rink »

sirmorris wrote: For your next step down the tech history route you could try writing the code out on paper and then have assembling it using the mnemonic translation chart at the back of the ZX81 manual..
Pfft. In my day, you had to figure out the opcodes yourself.
palmheads
Posts: 40
Joined: Thu Apr 30, 2009 8:15 am

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by palmheads »

Thanks guys! Its quite cool how it all comes together!!

I've also got an example from the original ZX Assembler manual where it prints stars on the screen working in pasmo!

I even was interested in looking at why CALL 0808 prints a character to the screen in ZXAS 2, so looked at the ZX81 Rom Disasembly book pdf (Melbourne House) and found CALL 07F1 is the actual "PRINT_CH" routine. That also works!! I imagine somewhere there will be a CALL todo a NEWLINE keypress etc.

My overall goal of all this is to try & port the classic game "Thrust" to the ZX81. It might take me years, but with all the documentation/examples around for programming the ZX81, I think it might be doable!

Thrust did have a speccy version which might be handy in the future for reference
http://www.worldofspectrum.org/infoseek ... id=0005245

cheers
Daryn
dr beep
Posts: 2079
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by dr beep »

palmheads wrote:Thrust did have a speccy version which might be handy in the future for reference
http://www.worldofspectrum.org/infoseek ... id=0005245

cheers
Daryn

For reference only indeed. The ZX81 has lowres and the ZX Spectrum has pixelmovement (wel the ZX81 has Hires, but that is another story when you just started printing on the ZX81). This gives me however the idea to code a MOONLANDER in 1K Hires (after all other ideas are done offcourse)!
palmheads
Posts: 40
Joined: Thu Apr 30, 2009 8:15 am

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by palmheads »

Moonlander in hi-res would be a great idea for a 1k game!

One cool thing about the game Thrust, its been ported to the Vectrex (6809 assembly with some C) with sourcecode:
http://www.emix8.org/static.php?page=Ve ... rustSource

And also the C16 (6502 assembly) has been disassembled
http://plus4world.powweb.com/software/Thrust
http://plus4world.powweb.com/dl/source/ ... source.zip

Not that having 6502 & 6809 sources would be that helpful, but just seeing the labels used, what each code snippet does etc might be quite handy in structuring a ZX81 version.

Also if it was ported to the C16 with 16k, it might fit well into a ZX81 with 16k & pseudo hi-res/hi-res.

cheers
Daryn
daybyter
Posts: 17
Joined: Wed Nov 23, 2016 11:03 pm

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by daybyter »

What were the sz81 settings to run the hello world example? I tried 1k,4k and 16k with no luck so far. Even a cut n paste from the forum posting just give me a blank screen.

Seems like I'm overlooking something simple... :cry:

TIA
olofsen
Posts: 189
Joined: Wed Jan 08, 2014 12:29 pm

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by olofsen »

Does the attached slightly modified version work, with just RUN and normal sz81 settings?
Attachments
helloworld.zip
(2.94 KiB) Downloaded 222 times
dr beep
Posts: 2079
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by dr beep »

Your code on EightyOne
HELLO.png
(123.32 KiB) Downloaded 805 times
User avatar
blittled
Posts: 229
Joined: Fri Dec 19, 2008 3:04 am
Location: Northwestern Pennsylvania, USA

Re: "Hello World" for pasmo & ZX Assembler 2 using MMCoYZX81

Post by blittled »

The link http://edu.i-lo.tarnow.pl/inf/retro/005 ... o/0005.php seems to be broken.

Even though I took 6502 assembly language programming at the university I went to, it wasn't until I spent hours using the Artic ZX-Assembler on my trusty TS1000 that I really learned assembly and some of the programming techniques I use today. My parents thought I was wasting my time on the TS1000 but 10 years later I landed a job that required Z80 assembly :D

Edit: Googled Artic ZX Assembler and found a new link for the broken one. http://eduinf.waw.pl/inf/retro/005_zx81_info/0005.php
Last edited by blittled on Thu Feb 16, 2017 8:07 pm, edited 1 time in total.
2X Timex Sinclair 1000, ZX81, ZX80Core, 5X 16K Ram Pack, ZXBlast, ZX P file to Ear Input Signal Converter, Elf II
Post Reply