M/C Part 15 This concludes the sub-series of summaries which has been spread over the last couple of issues. In this part, I'll list the various uses of ROM and DOS subroutines, although to get further details you can have a look at the specific stuff in past articles. If you're too stingey (are you listening Ross?) to buy back issues of Fred, then I can supply them all on any disk you send me with an SAE. I'm that sort of guy really. ROM SUBROUTINES --------------- When using ROM subroutines, page RAM0 (the system page) in at section B of the memory map. (lmpr = %000111111 = 31) Jump Table Values 1. Memory Transfer. JFARLDIR #012D Copies (PAGCOUNT=#5B83) 16k pages + (MODCOUNT=#5B84) bytes from page A, offset HL to page C, offset DE. Paging on entry/exit unimportant and unchanged. JFARLDDR #0130 A LDDR version of FARLDIR, counting backwords instead of forwards. 2. Floating Point Calculator Routines. JGETINT #0121 Unstacks and rounds number from calculator stack into HL, BC and lsb into A. Error if no. not in range 0-65535. JSTKFETCH #0124 Unstacks from calculator stack to AEDCB. JSTKSTORE #0127 Stacks AEDCB onto calculator stack. On exit, HL holds new STKEND. JSBUFFET #0124 Unstack details of string & copy it into buffer in system page. Error if string is longer than 255 chars, or the null string. On exit, DE points to start of buffer, BC holds string length, A is a copy of C. JSTRS #017E Takes number from calculator stack & forms an ASCII version for printing etc. in buffer at #5BA0. On exit, DE holds #5BA0, BC holds number of chars in buffer. 3. Graphics Routines. JPUT #0133 Puts a block of data onto a mode 3 or 4 screen. C holds X coordinate (byte accuracy 0-255). B holds Y coordinate 0 (top) - 191 (bottom). HL points to data. 1st & 2nd bytes = width (bytes) & height. A holds option: 0 = overwrite (with inverse option) 1 = XOR 2 = OR 3 = AND 4 = overwrite (no inverse option - faster) 5 = mask HL' points to mask, same size as block of data without first two size bytes. Data must be in either #4000-#7FFF or #E000-#FFFF in screen page. JGRAB #0136 Stores a block of data from a mode 3/4 screen to a buffer. Entry:- C holds X coordinate (byte accuracy, 0-255). B holds Y coordinate 0 (top) - 191 (bottom). E holds width (bytes). D holds height (pixels). Screen used is in CURSCRNP. On exit:- DE points to address in buffer of data (in 8k after screen). BC holds length including extra 3 bytes at start: 0,x,y. JPLOT #0139 Plot pixel of current attributes on current screen. B holds Y coordinate (0-191 as above). Mode 3 with FATPIX=0:- HL holds X coordinate (0-511). Other modes:- C holds X coordinate (0-255). JDRAW #013C Draws line of current attributes on current screen. C/HL (as above) pixels horizontally. B pixels vetically. D: 01 = down/ no movement. FF = up. E: 01 = right/ no movement. FF = left. Error if lines goes over screen edge. JDRAWTO #013F Draws line of current attributes on current screen from current position: C/HL (as above) holds X coordinate. B holds Y coordinate (as above). JCIRCLE #0142 Draws circle of current attributes on current screen. C holds X coordinate of centre. B holds Y coordinate (as above) of centre. HL holds offset (in pixels) from left side of screen. A holds radius. JFILL #0145 Fills area of current mode 3/4 screen. DE points to 16*16 pixel pattern to use/ 0 = solid fill with current PEN. Pattern stored like UDG. C holds X coordinates (0-255) of point to fill from. B holds Y coordinate (as above). In mode 3 with thin pixels, HL holds X offset from left side. A: 00 = Make 6k template after 24k screen to use. 01 = Use existing template. JROLL #014B Move part of current screen left/ right/ up/ down. A: 00 = SCROLL (no wrap - fills with current screen cols.) FF = ROLL (with wrap). B holds no. of pixels to move. C: 01 = left. 02 = up. 03 = right. 04 = down. E holds width of block in pixels. D holds height of block in pixels. MUST BE EVEN. L holds X coordinate (0-255). H holds Y coordinate (as above). JCLSBL #014E Clear entire screen if A=0, else clear upper screen. JCLSLOWER #0151 Clear lower screen & select channel K. 4. Other Useful Routines. JBEEP #016F Makes a beep DE-1 cycles long at period HL*8 T-states. JSENDA #0181 Send the byte in A to the parallel printer. Port to use held in LPTPRT1 (#5A10). Loops until printer acknowledges READY etc, and byte has been transmitted. Error if ESC is pressed. Only A and BC used. Other ROM Resources ------------------- 0004 POP HL 0005 JP (HL) 0006 JP (IY) 0016 JP (BC) 002D JP (IX) 0033 JP (DE) - A call to #0004 returns your address in HL. CALL #0005 is equivilent to CALL (HL), which doesn't exist as an op-code. Similarly, CALL #0006 is equivilent to CALL (IY), etc. 0008 Error handler. Also used to call DOS. (RST 08) 0010 Print char in A to current channel. (RST 10) 0035 DJNZ 0035 : RET - Useful for uncontended timing. 005C OUT (hmpr),A JP (HL) 005F LD A,B OR C DEC BC JR NZ,005F RET - Useful for uncontended timing. 008F LDIR : RET 0092 LDDR : RET 0095 CPIR : RET 0098 CPDR : RET 009B OTIR : RET 009E OTDR : RET - Large blocks will run significantly faster in ROM. (About 8%) FLOATING POINT CALCULATOR ------------------------- Numbers and details of strings stored on FPC stack, 5 bytes each. Integer: (-65535 to +65535) 00; sign (00=+ve, FF=-ve); lsb; msb; 00 Real: exponent+#80; mantissa (4 bytes - 1st bit = sign: 0 +ve/ 1 -ve) String: page; start offset (8000-BFFF) lsb; msb; length lsb; msb Calculator called using RST 28 followed by list of command codes: (Full list in Tech. manual) NB. Top number is N2; next is N1. $2 and $1 similar for strings. Comparisons remove top two entries, and add 1 or 0 (T/F). 1. Numbers. 00 MULT N1*N2 01 ADDN N1+N2 03 SUBN N1-N2 04 POWER N1^N2 05 DIVN N1/N2 0F NOTE N1<>N2 10 NLESE N1<=N2 11 NGTRE N1>=N2 12 NLESS N1N2 2. Strings. 02 CONCAT $1+$2 (New string in workspace: entry on FPCS) 16 SNOTE $1<>$2 17 SLESE $1<=$2 18 SGRTE $1>=$2 19 SLESS $1<$2 20 SEQUAL $1=$2 21 SGRTR $1>$2 3. Any Entries. 06 SWOP Swop top two entries. 07 DROP Discard top entry. 1C SWOP13 Swop 1st and 3rd entries. 1D SWOP23 Swop 2nd and 3rd entries. 25 DUP Duplicate top entry. 4. Others. 1E JPTRUE Do a JR if top value (discarded) is 1. 1F JPFALSE Do a JR if top value (discarded) is 0. 20 JUMP Do a JR. (In list of command codes) Calculator has its own B register - BREG. It starts like Z80's B when called. 21 LDBREG Load BREG with next byte. 22 DECB Do a DJNZ with BREG and the next byte. 23 STKBREG Stack BREG as a full 5 byte number. 24 USEB Take next command code from BREG. 26 ONELIT Stack next byte as integer no. 27 FIVELIT Stack next 5 bytes on FPCS. 28 SOMLIT Next byte specifies no. of bytes to stack. 31 RESTACK Ensure last value is in 5 byte form. 32 POWR2 Calculate 2^ top entry. 33 EXIT Finish using calculator. 34 EXIT2 Finish and do a RET. 4. Memory Storage. There are six 5-byte memories for storing temporary results. C8+x STODx Store, then discard, top entry in memory x (0-5). eg. CA stores in memory 2. D0+x STOx Store, without discard, top entry in memory x (0-5). eg. D2 stores in memory 2. D8+x RCLx Stack the contents of memory x (0-5). eg. DA stacks the contents of memory 2. 5. Stacking Constants. E0 STKHALF Stack 0.5 E1 STKZERO Stack 0 E2 STK16K Stack 16384 E6 STKFONE Stack real version of 1 E9 STKONE Stack integer version of 1 EC STKTEN Stack 10 F0 STKHALFPI Stack PI/2 VECTORS ------- NMIV #5AE0 Non-maskable interrupt. Usually holds address of BASIC break routine. Switches in system page temporarily & provides its own stack. On entry:- LMPR status stored in NMILRP, SP stored in NMISP, AF & HL pushed onto old stack. (May have been paged out). FRAMIV #5AE2 Called by frame interrupt. Use all main registers. COMSV #5AE6 Called by COMMS interrupt. MIPV #5AE8 Called by MIDI-IN interrupt. A has just been read from MIDI port. MOPV #5AEA Called by MIDI-OUT interrupt. EDITV #5AEC Called before the editor when editing a line (or INPUT). RST08V #5AEE Called early in error handling. A= error code. Alternate registers selected, CHAD & CHDP copied to XPRT & XPRTP. DE points to the error code that follows RST 08 (an address 1 past that code is now on the stack). RST28V #5AF0 Called by floating point calculator with A holding next code. DE points to top of FPC stack. RST30V #5AF2 User RST. Jumped to by RST 30 (other vectors are called). CMDV #5AF4 Called with A holding character about to be syntax checked or executed. Normally a command code. EVALUV #5AF6 Called with A holding current character in expression being evaluated. MTOKV #5AFA Called if a potential keyword isn't recognised by the ROM. On entry, DE points to the potential keyword. On exit, conditions as follows:- Set zero flag if no match, else reset zero flag. Point HL to start of word & DE just past end of it. A holds command code. KURV #5AFE Called before the cursor is printed (by calling the address in MNOP). ROM1 is paged in. DOS INTERFACING --------------- Please note: The following applies to SAMDOS. MasterDOS should work with all of the hook codes, but directory structure etc. is different. See official documentation for details. Entry to the DOS is through the error handler: ie. RST 08 DB x where x is the hook code. On occasions a UIFA (user info file area) 80 bytes long is needed. A confirmation DIFA is sometimes created at UIFA+80 by a routine. See official documentation for further details. Hook Codes ---------- INIT #80 Looks for an AUTO file and initialises the DVARS. HGTHD #81 Gets a file header. Call with IX pointing to UIFA. DIFA returned. HLOAD #82 Load file with IX pointing to UIFA. Length: C holds no. pages; DE holds modulo 16k. Destination: HL points between #8000 and #BFFF. Page the right page into hmpr. HVERY #83 Verify file. As HLOAD, but no data storage. HSAVE #84 Save file using complete UIFA pointed to by IX. HWSAD #95 Write to sector. D = track. E = sector. A = drive. HL = pointer in 64k addressing range. HRSAD #A0 Read from sector. D = track. E = sector. A = drive. HL = pointer in 64k addressing range. PCAT #A5 Directory listing to current stream. HERAZ #A6 Erase a file. IX points to UIFA.