Page 1 of 2
Learning Machine Code
Posted: Wed Jan 15, 2020 11:13 am
by Hedge1970
Hi all, looking for some advice, sorry for the long post, I wanted to at least try and describe where I am at...
I started programming the spectrum a few years ago. My aim to produce a game. My initial foray in BASIC lead me to believe in order to get the game playable I would need to do it in machine code (I did actually do it in Basic and posted it here last year, but...) So I started reading up.
The aim was to do this on a real ZX Spectrum 48k.
Google lead me to a couple of books and BigJons Road Race game
http://chuntey.arjunnair.in/?p=63
The books where Machine code for the Absolute Beginner by William Tang and Mastering Machine Code on your ZX Spectrum by Toni Baker. Then just lately I’ve watched Darryl Sloans Machine code tutorials
https://www.youtube.com › playlistWeb resultsMachine code tutorials (Darryl Sloan) - YouTube
Of course I also read the advice here so what’s the question
1. is there a good Spectrum Based assembler and disassembler.
I have been trying to use Zeus but the problem is the wide variance of interpretation between all the above materials. Example
Roadrace needed tweaking to work in Zeus
Toni Bakers examples from say Page 79 to 80 I can’t get to work in Zeus
Darryl Sloans example on Tutorial 2 wont work on Zeus.
So I could use ZX Spin Emulator for Darryl and all good, or I could use the program Toni provides called HEXLD2 all good but I don’t want to start a lengthy project only to find it won’t run native.
I like the idea of Zeus and it’s Dissasembler. I find it easy to use and essentially a nice environment to work in but it’s no good if I can’t practice what I am learning.
My next move is to go the (one of) route suggested here Notepad++ and Pasmo and see if I can get the above examples all working through that route but running in the real ZX.
I am sure it’s obvious to people who understand M/code what to do but from a standing start you can only leverage the tools around you and for me that is primarily books. But spending hours trying to not only understand what is written but then trying to figure out how to change it so it works in Zeus is just not effective.
I do feel it’s all doable but I feel I need a solid dev environment to move forward, so any help or advice - even how to get Zeus working - is most gratefully received.
Re: Learning Machine Code
Posted: Wed Jan 15, 2020 12:13 pm
by Ast A. Moore
Forget about Spectrum-native assemblers for serious development work. They’re fun for nostalgic reasons, but if you want any serious work done, you’ll need a so-called cross-assembler (that is, an assembler that produces code of an architecture different from what it runs on).
I’m afraid I can’t recommend you a particular one—I’m not a Windows user—but it does help to have a Spectrum-centric assembler, rather than a generic Z80 one. I’m lucky to have discovered zasm (and to which I have contributed in a small way). I made a special syntax highlighter for it and worked closely with the developer to essentially turn it into a small IDE.
That said, I think a combination of Notepad and some flavor of cross-assembler is the general route you should take. You’ll find it easier to use something more sophisticated than Notepad for writing and organizing your code; I’m sure there are plenty of programming-specific text editors on Windows.
Now, while a good assembler, which can generate TAP or TZX files (of which you have complete control) is a great boon, a more essential tool is your monitor/debugger. For that you’ll need an emulator that has one. Fuse has a pretty decent debugger, but nothing beats SpecEmu’s, in my book.
Note that trimming raw sources to fit your particular assembler is always going to be something you’ll need to do. However, as you become more savvy, you’ll (a) need to copy someone else’s code less and less, and (b) learn to do it with relative ease.
Oh, and I personally use real hardware only for the final stages of program testing (aside from a few very specific cases). Not only is it cumbersome and time consuming, but it also puts unnecessary stress on the 30-year-old hardware. While no particular emulator is perfect, they generally do a pretty good job for 99 percent of testing purposes.
Re: Learning Machine Code
Posted: Wed Jan 15, 2020 1:12 pm
by 1bvl109
I second every word you wrote, but can't help to be deeply impressed by the journey he embarked on. This is the way of the
Real Programmer. I liked ASZMIC, but that was for the
81.
https://media.oglaf.com/comic/feralchic.jpg
Re: Learning Machine Code
Posted: Wed Jan 15, 2020 1:16 pm
by Hedge1970
Thank you for the reply. Finding the right assembler and debugger is key, hopefully someone who is using one with success will pass by and post. It’s a shame nothing native seems worth while. Not sure about “serious” dev, of course in my dreams I would write the next Manic Miner or Elite, but in reality (if I am lucky) it will be closer to Snake
FYI Notepad++ is a full on text editor created as freeware by Don Ho and used worldwide by developers. Not to be confused with Notepad in windows, which while useful (and my go to everyday tool) is very basic indeed.
Re: Learning Machine Code
Posted: Wed Jan 15, 2020 2:05 pm
by 1bvl109
While browsing for something completely different i stumbled across this German emulator which seems to be a whole IDE. Assembler, BASIC-Compiler and what not. I've no idea, if the UI also talks English though.
http://www.jens-mueller.org/jkcemu/assembler.html
Re: Learning Machine Code
Posted: Wed Jan 15, 2020 2:22 pm
by Ast A. Moore
Hedge1970 wrote: ↑Wed Jan 15, 2020 1:16 pm
It’s a shame nothing native seems worth while. Not sure about “serious” dev, of course in my dreams I would write the next Manic Miner or Elite, but in reality (if I am lucky) it will be closer to Snake
Well, the thing is virtually no commercial Spectrum software was written on the same machine it was run on. That would have been immensely impractical. True, people often used another Speccy or even a less powerful machine (such as the TRS-80) for writing code and assembling it, but most software houses used much more powerful development platforms.
I made this post on a similar topic elsewhere. It’s worth repeating it here just to demonstrate the difference in the two approaches:
Hedge1970 wrote: ↑Wed Jan 15, 2020 1:16 pmNotepad++ is a full on text editor created as freeware by Don Ho and used worldwide by developers.
Oh, I see. Well, then you’re half way there. Get yourself a decent Z80 assembler, and use your favorite emulator to test your games!
Don’t get too hung up on the actual examples in “learn to program” books (although, they can be useful). The key knowledge you must acquire is the understanding of how the Spectrum actually works. The assembly language itself is a pretty straighforward affair and doesn’t require much learning per se. Browse this and any other Spectrum forum, and don’t hesitate to ask questions, both general and very specific.
Re: Learning Machine Code
Posted: Wed Jan 15, 2020 3:24 pm
by Alone Coder
If you want a handy native ZX Spectrum assembler, there is ALASM. A lot of software is written in it.
It needs TR-DOS, but I heard of MB02 version.
Re: Learning Machine Code
Posted: Thu Jan 16, 2020 6:02 pm
by Hedge1970
So I have gone with Pasmo as the cross assembler and Notepad++ as the text editor. I created a batch file that I can start from Notepad++ to run Pasmo, it takes two inputs, the file name I want and the file location - both of which are cut and pasted. I would like to help others who may stumble here but having only just set it all up and tested it I am not sure my way will be the most efficient... but here goes.
Pasmo can be downloaded here pasmo.speccy.org/
It is not the sort of program you install, rather it sits wherever you cut 'n' paste it. It uses the CMD or command line. You need to be in the same directory as Pasmo - As an example if Pasmo was just extracted to the C:\ drive - use the following
c:\Pasmo.exe --name
programname --tabbas
programname.asm
programname.tap
Instructions are here
http://pasmo.speccy.org/pasmodoc.html
I am using tapbas as it adds a Basic loader to the code
Once the TAP is created I then load that into Spectrum and then Type RANDOMIZE USR 32768 (note 32768 is where you started writing to.)
I am using Notepad++ a very good text editor to create my programs, it comes with many language syntax definitions out of the box including assembly. It also has a handy RUN command to let you run an external program such as Pasmo. I created the following Batch file and simply start it from within Notepad++ off the top menu called "Run".
Code: Select all
@ECHO OFF
SET/P filename="Enter File Name: "
SET/P directory="Enter Directory of Source File: "
E:\personal\computer\ZXSpectrum48K\programing\pasmo-0.5.3\pasmo-0.5.3\pasmo.exe --name %filename% --tapbas %directory%\%filename%.asm %directory%\%filename%.tap
MKDIR %directory%\TAP
MOVE %directory%\*.tap %directory%\TAP
pause
The file asks you for the source file name and the source file location then creates the TAP file in a Folder called TAP in the SourceFile location. Its much easier to do than it sounds as all you do is open explorer and follow the prompts and copy/paste return.
This solution has allowed me to run all the examples I have tried both from the books and also from Darryl Sloans Youtube videos.
Thanks for your help. I will get used to it a bit more then If you dont mind I am sure I will have some pretty low level but confusing questions
Re: Learning Machine Code
Posted: Thu Jan 16, 2020 6:46 pm
by Joefish
I use Crimson Editor for the same job.
You can define function keys to do command-line strings and so call PASMO on whatever file you're currently editing with a single keypress.
You can set another function key in Crimson Editor to launch an emulator like ZXSpin with a command-line parameter made from the current PATH\FILE name with .TAP added and it will launch the compiled .TAP file in the emulator.
If you've compiled with the --TAPBAS option then the .TAP should load, run and execute the machine code automatically when you load it into the emulator.
Re: Learning Machine Code
Posted: Thu Jan 16, 2020 7:46 pm
by Hedge1970
I’ll grab a copy of that as well, thanks.
Re: Learning Machine Code
Posted: Fri Jan 17, 2020 7:15 am
by PeterJ
I've mentioned this previously, but this three part tutorial from [mention]Shaun_B[/mention] really gave me the introduction I needed. It originally appeared in MicroMart magazine.
http://shaunbebbington.blogspot.com/201 ... i.html?m=1
You just need Pasmo which is an opensource command line assembler, notepad and an emulator.
Re: Learning Machine Code
Posted: Fri Jan 17, 2020 10:11 am
by Hedge1970
PeterJ wrote: ↑Fri Jan 17, 2020 7:15 am
I've mentioned this previously, but this three part tutorial from @Shaun_B really gave me the introduction I needed. It originally appeared in MicroMart magazine.
http://shaunbebbington.blogspot.com/201 ... i.html?m=1
You just need Pasmo which is an opensource command line assembler, notepad and an emulator.
Excellent and thank you I will also add this to the list of learning tools. Also thanks again to joefish, I had not realised zxspin could be run from command line so I have now edited the batch file run from Notepad++ to start Z Spin and load in the newly created .tap file from Pasmo. My Batch file is called RunPasmo.bat
Code: Select all
@ECHO OFF
REM NotePad RUN command "drive:\filepath\RunPasmo.bat $(FULL_CURRENT_PATH)"
REM $(FULL_CURRENT_PATH) is a command from Notepad++ for full path to current file
REM %~n1 Extracts file name without the type from $(FULL_CURRENT_PATH)
REM %dp1 Extracts just the file path from $(FULL_CURRENT_PATH)
REM Pasmo command line
E:\personal\computer\ZXSpectrum48K\programing\pasmo-0.5.3\pasmo-0.5.3\pasmo.exe --name %~n1 --tapbas %~dp1\%~n1.asm %~dp1\%~n1.tap
REM Make new directory in the path wher the .asm file is called TAP
MKDIR %~dp1\TAP
REM Put the new created .tap file in the directory TAP
MOVE %~dp1\*.tap %~dp1\TAP
REM Launch Spin
E:\personal\computer\ZXSpectrum48K\emulator\zxspin_0666emu\ZXSpin.exe %~dp1Tap\%~n1.tap
Re: Learning Machine Code
Posted: Fri Jan 17, 2020 5:27 pm
by Hedge1970
I have a question about knowing where in your code subroutines are. It really harks back to OpCodes and Assemblers vs Directly entering Hex. I expect I know the answer but I find it hard to believe
So if you look at page 93 of Mastering Machine Code ->
https://spectrumcomputing.co.uk/index.p ... id=2000237 here Toni Baker writes an example routine for scrolling the screen up or down. I have published my .asm file below. Please note I added the ORG 32768.
Code: Select all
ORG 32768
UPLD PUSH BC
PUSH DE
PUSH HL
LDIR
POP HL
INC H
POP DE
INC D
POP BC
RET
UP LD HL,#4020
LD DE,#4000
LD BC,#1AE0
LDIR
LD HL,#47E0
LD DE,#40E0
LD C,#20
LD A,#10
U_LOOP CALL UPLD
DEC A
JR NZ,U_LOOP
LD H,D
LD E,#E1
DEC BC
LD A,#08
U_BLANK LD (HL),#00
CALL UPLD
DEC A
JR NZ,U_BLANK
LD H,#5A
LD D,H
LD A,(#5C48);bordcr
LD (HL),A
LDIR
RET
DOWNLD PUSH BC
PUSH DE
PUSH HL
LDDR
POP HL
DEC H
POP DE
DEC D
POP BC
RET
DOWN LD HL,#5ADF
LD DE,#5AFF
LD BC,#1AE0
LDDR
LD HL,#501F
LD DE,#571F
LD C,#20
LD A,#10
D_LOOP CALL DOWNLD
DEC A
JR NZ,D_LOOP
LD H,D
LD E,#1E
DEC BC
LD A,#08
D_BLANK LD (HL),#00
CALL DOWNLD
DEC A
JR NZ,D_BLANK
LD H,#58
LD D,H
LD A,(#5C8D);ATTR_P
LD (HL),A
LDDR
RET
She then provides the Basic program to use the Machine Code. In the Basic Program depending on keyboard key "7" or "6" being pressed - lines 160 and 150 - the Machine Code subroutines UP or DOWN are called. Of course she has not instructed you where (memory location) to build the Machine code to - in my case I used 32768 - which means she can only tell you where in the code sub-routine up and sub-routine down are by referencing the labels UP and DOWN so she states USR
up and USR
down at the relevant points. In order to get it working I added the reference USR 32841 and USR 32779 at the correspond position in Basic, but I only know these locations by actually counting the Bytes used in the code - referencing page 93 above I literally count the bytes from 32768 onwards until I reach Label UP and Label Down.
The question is - Is there a way of knowing by looking at the OPcode above what the byte count is to a specific point in your code or do you just need to keep track? If you need to keep track how would you do this in a large program like ManicMiner or Elite?
I do hope that makes sense.
Code: Select all
10 DIM A$(22,36)
20 FOR I = 1 TO 22
30 LET B$ = CHR$ (INT (96*RND) + 32)
40 FOR J = 0 TO 5
50 LET B$ = B$ + B$
60 NEXT J
70 LET A$(I) = CHR$ 16 + CHR$ INT (8*RND) + CHR$ 17 + CHR$ INT(8*RND) + B$
80 PRINT A$(l)
90 NEXT I
100 LET A = 1
110 PAUSE 0
120 LET B$ = lNKEY$
130 LET B = A + 1 :IF B = 23 THEN LET B = 1
140 LET C = A – 1 :IF C = 0 THEN LET C = 22
150 IF B$ = "6" THEN PRINT AT 0,USR down;A$(C): LET A = C
160 IF B$ = "7" THEN PRINT AT 21,USR up; A$(A): LET A = B
170 INPUT ""
180 GO TO 110
Re: Learning Machine Code
Posted: Fri Jan 17, 2020 6:02 pm
by Joefish
PASMO has an option to let you save out the 'Symbol Table' during compilation.
This dumps the value of every variable (and thus location of every label), in alphabetical order, to a text file at the end of compilation.
I sometimes use it to calculate the size of the code or data by putting a label at the beginning and end, calculating a variable from the difference, and giving it a name like a taxi firm ("___A1A!!!AAA_TAXIS") so it appears high up in the alphabetical list.
(Which reminds me of the most obscure joke in an animation ever seen - the sign for "Thigmo Taxis" on the side of a building during a chase scene in Little Rodentia in Disney's Zootropolis / Zootopia. "Thigmotaxis" is the tendency of rodents to run alongside walls instead of out in the open. Rather than being some sort of rodent agoraphobia, they've actually evolved a reassuring tactile sensation ('thigmo' = 'tactile') when moving along a wall ('taxis' = 'movement', Ancient Greek) on one or the other side of their body; it's quite literally how they get from one place to another).
Re: Learning Machine Code
Posted: Fri Jan 17, 2020 7:03 pm
by Hedge1970
Thanks Joefish, I’ll take a look later.
Re: Learning Machine Code
Posted: Fri Jan 17, 2020 7:36 pm
by AndyC
Another trick is to start your code with a series of JP instructions to the entry points. Since each is three bytes long the addresses are easily predictable and won't move each time you reassemble the listing.
Re: Learning Machine Code
Posted: Fri Jan 17, 2020 7:50 pm
by Hedge1970
That should work really well for this. Thanks
Re: Learning Machine Code
Posted: Tue Jan 28, 2020 8:55 pm
by Hedge1970
Hi All,
So I have been busily working my way through some examples. Feeling quite good but with lots to learn and then today I got hit with something that I had assumed I knew …
ORG 32768
I thought that this statement meant that my code would start at the address 32768 and then in order to execute that code I then input RANDOMIZE USR 32768. So this all works, but tonight I needed to shift the code 54bytes higher so I did
ORG 32822 and then RANDOMIZE USR 32822 and I get an error - same code as before. Then when I type RANDOMIZE USR 32768 it all runs as expected??? Have I miss understood the ORG and if so how would I decide where to put machine code in the memory?
For reference here is the code. Not very exciting and needs a CLR before running...
Ideally it requires
700 RANDOMIZE USR 32768
710 INPUT LINE A$
720 RANDOMIZE USR 32781
Then it allows you to enter co-ords - nothing happens except you can enter more co-ords the actual move sub will come once I can relocate the code to a new part of the machine i.e. 32822
Thanks for any and all input.
Code: Select all
ORG 32768
JP start ; 3 BYTES
JP move ; 3 BYTES
s_print POP HL ; pulls address off stack
LD A,(HL) ; This refers to first byte of defm
INC HL ; alter +1 return byte address
PUSH HL
AND A ; Reset Carry and Set Zero if 0
RET Z ; when we reach defb #00 return to JP board
RST #10 ; prints message to screen
JR s_print
start XOR A ; A=0, Reset Carry
LD (#5C3C),A ; TVFlag
CALL s_print ; pushes the address of next instruction i.e. the space below onto stack
DEFM " 12345678",#0D
DEFM "1",#90," ",#90," ",#90," ",#90," 1",#0D
DEFM "2 ",#90," ",#90," ",#90," ",#90,"2",#0D
DEFM "3 3",#0D
DEFM "4 4",#0D
DEFM "5 5",#0D
DEFM "6 6",#0D
DEFM "7",#90," ",#90," ",#90," ",#90," 7",#0D
DEFM "8 ",#90," ",#90," ",#90," ",#90,"8",#0D
DEFM " 12345678"
DEFB #00 ;sets the byte to 0 - end sub routine s_print
JP board
row LD A,#04
row_2 LD (HL),C ;color next draughts piece
INC HL
INC HL
DEC A
JR NZ,row_2
ADD HL,DE ;next row
BIT #0,L
JR NZ,row_3
INC HL
INC HL
row_3 DJNZ row
RET
board LD HL,#5800 ;PrintAt 0,0 attribute
LD DE,#0016
LD C,#0A
yellow_1 LD B,#0A ;B=10 row 2 yellow, 4 black 4 white
yellow_2 LD (HL),#30
INC HL
DJNZ yellow_2
ADD HL,DE
DEC C
JR NZ,yellow_1
LD HL,#5821
LD E,#18
LD C,#08
white_1 LD B,#08
white_2 LD (HL),#38
INC HL
DJNZ white_2
ADD HL,DE
DEC C
JR NZ,white_1
LD HL,#5822
DEC E
LD BC,#0307
CALL row
LD BC,#0200
CALL row
LD BC,#0302
CALL row
RET
move LD HL,(#5C4B) ;VARS system variable
INC HL
LD E,(HL)
INC HL
INC HL
LD A,(HL)
CP #E2 ;STOP Sym A
JR NZ,a$_ok
RST #08
DEFB #FF
a$_ok LD HL,#02C6
LD (#5C42),HL
LD A,#01
LD(#5C44),A
RET
Re: Learning Machine Code
Posted: Tue Jan 28, 2020 9:33 pm
by Ast A. Moore
Assembler directives and pseudo-instructions are pretty specific to a particular flavor of assembler, so it’s hard to tell without knowing your setup. I quickly tried your code in zasm and, after a tiny bit of cleanup, it worked fine. I could easily relocate your code anywhere in RAM (not that anything would suggest I couldn’t).
Re: Learning Machine Code
Posted: Tue Jan 28, 2020 9:39 pm
by Hedge1970
Of course should have realised. I am using Pasmo as the assembler and and standard text editor to write the assembly. It’s running through ZX Spin.
Thanks for running the code and glad it worked I am now thinking I should use hex instead of decimal in the ORG statement - I’ve had issues in the code with decimal.
It’s all shut down now but I will try it tomorrow.
Re: Learning Machine Code
Posted: Tue Jan 28, 2020 9:53 pm
by catmeows
Why USR 32781 ? Where it should jump ?
Anyway, I'm not seeing any issues with your code. Still, I would not use $ in label, it can have special meaning.
Re: Learning Machine Code
Posted: Tue Jan 28, 2020 10:20 pm
by Ast A. Moore
Hedge1970 wrote: ↑Tue Jan 28, 2020 9:39 pm
I am using Pasmo as the assembler and and standard text editor to write the assembly. It’s running through ZX Spin.
I see. Well, I’m not familiar with either, but off the top of my head, I’d suggest putting a space in front of the ORG statement. Some assemblers assume that a letter at the first position of a line is a label, rather than a (pseudo-) instruction/directive.
Re: Learning Machine Code
Posted: Tue Jan 28, 2020 10:52 pm
by lister_of_smeg
Ast A. Moore wrote: ↑Tue Jan 28, 2020 10:20 pm
I see. Well, I’m not familiar with either, but off the top of my head, I’d suggest putting a space in front of the ORG statement. Some assemblers assume that a letter at the first position of a line is a label, rather than a (pseudo-) instruction/directive.
Yup, this. And as this results in you having no defined origin, I would hazard a guess that Pasmo defaults to 32768 in such a case.
Re: Learning Machine Code
Posted: Wed Jan 29, 2020 9:00 am
by Hedge1970
Hey I did not see these last night and tried the hex before coming to work but that failed.
Will give this a shot tonight
Re: Learning Machine Code
Posted: Wed Jan 29, 2020 9:41 am
by uglifruit
Just as a test it appears to work okay for me. Should the you mention 32781 be 32771 ? (to the second jp command) - though this gives a N Statement Lost Error.
Relocating the routine to a different address (different org instead of 32768), and calling it there seems to work the same.
I'm using PASMO on a mac: with these arguments:
pasmo --tapbas try/try.asm try/try.tap
Just as a 'did you know' - finishing your assembly with END 32768 will compile the basic loader so it already does a Randomize 32768 when you launch it in your emulator.