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!)
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.