NOOB QUESTION: learning machine code

Anything QL Software or Programming Related.
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: NOOB QUESTION: learning machine code

Post by NormanDunbar »

Morning all.

I've written a quick and dirty job to do what Tinyfpga requested, almost exactly! It will open a console, check if the PE is installed, OUTLN (and CLS) the console if so, CLS it if not then print a ">" prompt, enable the cursor, request some input, then print whatever was input before suspending for 4 seconds and killing itself!

The zip file is created on SMSQ/E, so will not need any special care UNLESS extracted on Windows/Linux. Please extract on SMSQ or QDOS.

Happy to answer questions, and, in the next issue of the eMagazine, I will be starting a beginner's guide to QDOS. (If I remember!)
tinyfpga_zip.zip
(3.18 KiB) Downloaded 53 times
:D

Ok. The zip file was named "tinyfpga_zip" but that's not liked by the forum software. Save it, remove the extra ".zip" extension, then copy to QDOSSMSQ as usual and extract.

For some reason, I can't get the source to upload by itself. Sigh. Hence, the folloiwng large code chunk!

Code: Select all

;==============================================================
; A simple multi-tasking job for TinyFPGA to:
;
; Open #n,con_
; OUTLN #n,310,60,50,300
; CLS #n
; BORDER #n,1,7
; INPUT #n, some_text_from_user
; Die!
;==============================================================
; Norman Dunbar
; 20 November 2021.
;==============================================================

;--------------------------------------------------------------
; Some definitions to make life simple(r)!
;--------------------------------------------------------------
WHITE       equ 7               ; White colour
BLACK       equ 0               ; Black colour

BORDCOLOUR  equ WHITE           ; Border colour
BORDWIDTH   equ 1               ; Border width
PAPER       equ BLACK           ; Paper colour
INK         equ WHITE           ; Text colour

CON_W       equ 310             ; Console width
CON_H       equ 60              ;    "    height
CON_X       equ 50              ;    "    X position
CON_Y       equ 300             ;    "    Y position

BUFFERSIZE  equ 256             ; User input buffer size

;--------------------------------------------------------------
; I use GWASS as my assembler, it has the QDOS traps etc built
; in. It doesn't however, have the PE stuff, so these two are
; required.
;--------------------------------------------------------------
IOP_PINF    equ $70             ; Get PE information
IOP_OUTL    equ $7a             ; OUTLN

;--------------------------------------------------------------
; As mentioned, these are built in to GWASS and are not 
; required. QMAC will probably require them, if so, uncomment.
;--------------------------------------------------------------
;UT_CON      equ $c6             ; Open a console, border, etc
;SD_CLEAR    equ $20             ; CLS
;IO_SBYTE    equ $05             ; Print one byte to channel
;SD_CURE     equ $0E             ; Enable cursor
;IO_FLINE    equ $02             ; Fetch a line of text plus LF
;UT_MTEXT    equ $d0             ; Print some text
;MT_SUSJB    equ $08             ; Suspend a job
;MT_FRJOB    equ $05             ; Force remove a job

;--------------------------------------------------------------
; Job's require a header. This is basically boilerplate, except
; for the job name's length and the name of the job. This will
; need to be EXEC/EXEC_W/EX or EW'd to execute it.
;--------------------------------------------------------------
Start
        bra.s open_console      ; Skip over job header
        dc.l 0                  ; 4 bytes, can be any value
        dc.w $4afb              ; Job flag, must be $4afb
        dc.w 8                  ; Length of job name
        dc.b "TinyFPGA"         ; Bytes of job name


;--------------------------------------------------------------
; Needs a channel open first. This can be done in a couple of
; ways, but this is probably the easiest. It will open a con_
; channel of the required size and border it.
;
; UT_CON uses all of the following from con_def and outln_def
; IOP_OUTLN only uses the latter.
;--------------------------------------------------------------
con_def
        dc.b BORDCOLOUR         ; Border colour
        dc.b BORDWIDTH          ; And width
        dc.b PAPER              ; Paper/strip colour
        dc.b INK                ; Ink colour

outln_def
        dc.w CON_W              ; Width
        dc.w CON_H              ; Height
        dc.w CON_X              ; X pos
        dc.w CON_Y              ; Y pos

open_console
        lea con_def,a1          ; Parameters
        move.w UT_CON,a2        ; C6 = CONSOLE required
        jsr (a2)                ; Open Console & set params
        bne die                 ; If it failed - bale out

;--------------------------------------------------------------
; We only get here if it worked. A0 now holds the channel id.
; Most, if not all, QDOSMSQ code preserves the A0 register.
;--------------------------------------------------------------
; Check if the PE is installed. If not, ignore the error and
; skip to handle clearing the screen "manually".
;--------------------------------------------------------------
check_pe
        moveq #IOP_PINF,d0      ; IOP_PINF
        moveq #-1,d3            ; Timeout (Preserved)
        trap #3
        tst.l d0                ; Errors?
        bne.w cls_console       ; PE missing


;--------------------------------------------------------------
; PE is present.
;--------------------------------------------------------------
; OUTLN the window, Setting D2 to zero will CLS the window for
; us as well. D3 (timeout) was preserved in IOP_PINF as was A0 
; (channel id for the console).
;--------------------------------------------------------------
outln_console
        moveq #IOP_OUTL,d0      ; IOP_OUTL
        moveq #0,d1             ; No shadows
        moveq #0,d2             ; CLS as well, handy!
        lea outln_def,a1        ; Window sizes (W,H,X,Y)
        trap #3                 ; Do it
        tst.l d0                ; Errors?
        bne die                 ; Yes, bale out
        bra.s con_prompt        ; Skip PE missing stuff

;--------------------------------------------------------------
; PE is missing.
;--------------------------------------------------------------
; Clear the screen. The timeout and channel ID have been 
; preserved over the last two routines.
;--------------------------------------------------------------
cls_console
        moveq #SD_CLEAR,d0      ; CLS whole window
        trap #3                 ; Do it
        tst.l d0                ; Any errors, probably not
        bne die                 ; Yes, bale out

;--------------------------------------------------------------
; Print a ">" prompt to the channel. Timeout/channel Id still
; preserved.
;--------------------------------------------------------------
con_prompt
        moveq #IO_SBYTE,d0      ; Print one character
        moveq #'>',d1           ; The prompt character
        trap #3                 ; Do it
        tst.l d0                ; Any errors?
        bne die                 ; Yes, bale out

;--------------------------------------------------------------
; Enable the channel's cursor. We need one to get input from
; a console channel. Timeout & channel id preserved still.
;--------------------------------------------------------------
con_cursor
        moveq #SD_CURE,d0       ; Enable cursor
        trap #3                 ; Do it
        tst.l d0                ; Errors?
        bne die                 ; Yes, bale out

;--------------------------------------------------------------
; Grab some input from the console. The timeout and channel id
; are still valid. We point A1 at input_buffer+2 as we need the
; start of the buffer to hold the length of the text that
; follows.
;--------------------------------------------------------------
get_input
        moveq #IO_FLINE,d0      ; Fetch input with Linefeed
        move.w #BUFFERSIZE,d2   ; How big is my buffer?
        lea input_buffer+2,a1   ; Input buffer space
        trap #3                 ; Fetch input D1.W = size
        tst.l d0                ; Errors?
        bne die                 ; Fraid so

        lea input_buffer,a1     ; The buffer start this time
        move.w d1,(a1)          ; Store the input size (inc LF)
        bra print_input         ; Skip over inoput buffer

input_buffer
        ds.w    BUFFERSIZE+2    ; Buffer for data input


;--------------------------------------------------------------
; Print the input that the user gave us, including the line
; feed at the end. A1 points to the text's word size, D3 will
; be corrupted by this vector call (timeout) but the channel
; id in A0 will not.
;--------------------------------------------------------------
print_input
        move.w UT_MTEXT,a2      ; Print a string of bytes
        jsr (a2)                ; Print it
        bne.s die               ; Ooops, error

;--------------------------------------------------------------
; Suspend the job for a couple of second to let the user see
; the output. Then die. Will corrupt A0 but who cares!
;--------------------------------------------------------------
suspend_job
        moveq #MT_SUSJB,d0             ; Suspend a job
        moveq #-1,d1            ; This job
        move.w #200,d3          ; 4 seconds is 200 frames
        movea.l #0,a1           ; No byte to be cleared
        trap #1                 ; Suspend the job
                               
;--------------------------------------------------------------
; The job is complete, remove it from the system. Any error
; codes in D0 are copied to D3 ready for EXEC_W/EW to collect.
; EXEC/EX don't bother.
;--------------------------------------------------------------
die
        move.l d0,d3            ; Any errors?
        moveq #MT_FRJOB,d0      ; Force Remove a job
        moveq #-1,d1            ; -1 means "this job"
        trap #1                 ; Kill this job

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Tinyfpga
Gold Card
Posts: 252
Joined: Thu Sep 27, 2018 1:59 am

Re: NOOB QUESTION: learning machine code

Post by Tinyfpga »

Thanks very much Norm.


User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: NOOB QUESTION: learning machine code

Post by pjw »

Tinyfpga wrote:<>I mentioned that I thought I had asked the question posted above, in an other post. This morning I found that I had done so and that pjw had kindly replied with an assembly example:- viewtopic.php?f=3&t=2839&start=110#p44063
Yes, I did. Some 12 lines of code (plus some data and directives)
seemed to answer your question without causing, I hope, too much
confusion.

But now for some confusion: There are two sets of mnemonics in use on
"QL" systems: The old Qdos mnemonics and the new SMS(Q) mnemonics.

So what are the mnemonics in question here? Well, mnemonics are sort
of "the language Qdos/SMSQ". I dont have the proper words for all
this, so perhaps Im the wrong person to try to explain it, but my
point is that the mnemonics in a way describe the shape and structure
of the operating system. They include things like

Code: Select all

sb_buffb equ     $00      ; long     input (etc) buffer base
sb_buffp equ     $04      ; long     ... and pointer
which replace offset numbers into data structures with (more or
less) meaningful names. Or

Code: Select all

iob.test equ     $00   ; TEST input
iob.fbyt equ     $01   ; Fetch BYTe from input
iob.flin equ     $02   ; Fetch LINe from input
with give functional names to trap (function) codes.

They are not part of the assembler instruction set. A different OS
will use a different set of mnemonics even if it were otherwise
written in MC68 assembler.

The old mnemonics described Qdos, the new describe SMS(Q)(E). I dont
have the exact dates and history of it at my fingertips, perhaps
people here do and will pipe up, but when Allan Sugar bought and
killed Qdos, Tony Tebby had to re-invent Qdos anew - SMS(Q). He also
invented a new set of mnemonics for it. Since then, the bulk of
functional assembler code that has been written for the "QL",
including the OS itself, loads of utilities, toolkits etc, have been
written using the SMSQ mnemonics.

When I started writing assembler I used the Qdos mnemonics, later I
started learning the new and finally switched over. I can still read
and understand the old ones, but would never use them myself any more
except, possibly, to fix an old toolkit, or so.

I would advise anyone learning about Qdos/SMSQ today to use the new
mnemonics, as these are more complete, consistent, and cover the whole
field, including facilities that didnt exist back in the Qdos days. Im
not sure there even is a complete set of "official" Qdos mnemonics as,
AFAIK, the source code for Qdos has never been released.

Ideally, one should be acquainted with both sets, but its tough for
beginners, so stick with one at the time, either way.


Per
dont be happy. worry
- ?
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: NOOB QUESTION: learning machine code

Post by NormanDunbar »

I would agree, stick to the SMSQ/E trap codes etc. I'm stuck in the stone age with the QDOS ones due to having used them for far too long!

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Derek_Stewart
Font of All Knowledge
Posts: 3928
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: NOOB QUESTION: learning machine code

Post by Derek_Stewart »

Hi,

Is it appropriate to use SMSQ/E definitions on a QL fitted with QDOS or Minerva roms?


Regards,

Derek
User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: NOOB QUESTION: learning machine code

Post by tofro »

Derek_Stewart wrote:Hi,

Is it appropriate to use SMSQ/E definitions on a QL fitted with QDOS or Minerva roms?
Yes, it is. They're just different names for the same thing. As long as you stay within QDOS capabilities, you're fine.

(I never managed to get used to the SMSQ/E definitions and still use the old ones, mainly. Only the ones that don't have QDOS equivalents I seem to get along with)


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: NOOB QUESTION: learning machine code

Post by NormanDunbar »

Derek_Stewart wrote:Hi,

Is it appropriate to use SMSQ/E definitions on a QL fitted with QDOS or Minerva roms?
As tofro says Derek, it's fine, you can even mix and match in the same code. When all is said and done, they names used are simply equates, as in:

Code: Select all

UT_CON equ $c6       ; For QDOS
OPW_CON equ $c6      ; For SMSQ/E
So, there's no problem using either, or, or both!

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Derek_Stewart
Font of All Knowledge
Posts: 3928
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: NOOB QUESTION: learning machine code

Post by Derek_Stewart »

Hi,

Thank you for the information.

I know that the QDOS / SMSQ/E definitions are equates or static variables defined at the start of the the assembley programme, or in a header file.

I am just asking what is the standard , if any, that should be used on each operating system, i.e. QDOS/Minerva and SMSQ/E.

Personally, I use the SMSQ/E style, as the modern QL operating systems use SMSQ/E.


Regards,

Derek
User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: NOOB QUESTION: learning machine code

Post by pjw »

I too sometimes cant remember the new names and then revert to some of
the more familiar "paleomnemonics" of yore:

Code: Select all

	lea key,a2
	move.w $110,a2
	..
	move.w $118,a2
	jsr
	..
	move,l $58(a6),a1
	..
Traps are still 1,2,3,4 to me, and errors still -1 to -23, or whatever
number they have reached. Back then Include files with all the
definitions werent always easy to come by so yourd still have to look
up the numbers and add the definitions yourself.

At present the hardest part sometimes is figuring out which include
file contains the definitions you want. Thats where FiFi - the
DuckDuckGo of QL - comes in handy..

Changing old habits is hard, especially when youre a zillion years
old! Its when starting out you still have a chance..


Per
dont be happy. worry
- ?
User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: NOOB QUESTION: learning machine code

Post by pjw »

Derek_Stewart wrote:<>
I am just asking what is the standard , if any, that should be used on each operating system, i.e. QDOS/Minerva and SMSQ/E.<>
There is no "should" as such in QLdom. Technically, its just a matter of choice.
Im rooting for the new system for the reasons outlined in my piece some posts back. And especially for "noobs": Do they really need to penetrate an additional layer of arcana before they can join the club?


Per
dont be happy. worry
- ?
Post Reply