home *** CD-ROM | disk | FTP | other *** search
/ Outlet 74 / outlet-74.mgt / ROMINFO.T < prev    next >
Text File  |  2021-04-18  |  20KB  |  1 lines

  1.                  A Journey into the Spectrum ROM                                     29/01/90 Antony Purvis                                                                                      The  Spectrum  ROM  holds  a  myriad  of  useful  routines  andfunctions. Some of them are  useful  in  BASIC  programs  -  thescreen scroll routine at  address  3280  for  instance  -  whileothers can save time and effort when writing machine code.       In this article, I will explain what a few of the  more  usefulroutines do, and give details of how  to  use  them.  There  aretimes  when  the  m/c  programmer  needs  to   duplicate   Basicfunctions, so I have included some  of  these  too.  Well,  letsstart at the beginning, as someone once said!                                       00000 (0000h) USR 0 RST 0                    This is where the Spectrum arrives when  you  turn  it  on-  itclears the entire  memory,  sets  up  the  screen  colours,  andinitialises all the system variables. It  finally  displays  thecopyright message. Not terribly useful really!                                      00008 (0008h) USR 8 RST 8                    The Error restart. This routine takes the  value  of  the  byteimmediately  following  the  RST  8   command,   generates   theappropriate error message and returns control to BASIC.          For instance, following RST 08 with 6 will produce error report7, Return without Gosub,  and  similarly  a  value  of  23  willgenerate error report O Invalid Stream. This byte is also storedin the system variable ERRNR at 23610.                                             00016 (0010h) USR 16 RST 16                   The PRINT routine is one of the most useful  in  the  Spectrum.Its versatility can only  be  realised  when  it  is  used  frommachine code. The routine will take the character  whose  numberis held in the A register and print it to the currently selectedstream.                                                          It can send data to a printer via stream 3, or  to  the  screenvia stream 2, in which case the output is at the  current  printposition, using the current INK, PAPER, FLASH, BRIGHT  and  OVERvalues. This routine corrupts all registers though, so make sureyou PUSH them onto the stack first!                                                00040 (0028h) USR 40 RST 40                   This is the "Calculator" restart - it is extremely complex, andit would need the whole of this  article  to  even  explain  thebasics!                                                                            00056 (0038h) USR 56 RST 56                   This routine is called 50 times a second in  the  Speccy  -  itscans the keyboard, changing the appropriate  system  variables,then increments the real time clock held  at  locations  23672/3/4. It POPs an address from the stack,  which  it  jumps  to  oncompletion.                                                                           00654 (028Eh) USR 654                      This is the master key scan routine. It returns two  values  inthe D and E registers. The D register is returned with  a  valuewhich indicates which shift key is being pressed. The E value isbetween 0  and  39,  corresponding  with  the  40  keys  on  thekeyboard.                                                        If both shift keys are being pressed, the D register holds  thecode for CAPS SHIFT, and the  E  register  holds  the  value  ofSYMBOL SHIFT. If no keys are being pressed, then the DE registerpair is returned with a value of FFFF (65535) .                  If more than 2 keys are being pressed, or neither key  or  pairof keys is a shift key, the zero  flag  is  reset.  The  resultsreturned from this routine are  rather  complex,  so  this  nextroutine is designed to make the scan easier to use                                    00703 (02BFh) USR 703                      This will call the keyscan at 654 and decode the key value. TheCODE of the key, or combination of keys  that  were  pressed  isstored in the system variable LASTK  (23560).  Bit  5  of  FLAGS(23611) is set to show that a new key has been pressed.          In fact the  routine  checks  the  value  held  in  the  systemvariable MODE, which keeps track of whether the machine is in K,L, C, E, or G modes. This affects the final  value  returned  toLASTK.                                                                                00949 (03B5h) USR 949                      This is the routine responsible for the wonderful BEEP command.From machine code, the DE register pair should be loaded with  avalue equal to the time that the note should last  (in  seconds)multiplied by the frequency of the note. The  HL  register  pairshould hold INT ((437500/ frequency) -30.125).                   That sounds very complicated, because it  IS  complicated.  Forthe middle C note to be produced for one second, DE should  holdINT (261.63 * 1) and HL INT ((437500/261.63)-30.125). The 30.125is a constant to compensate for processor timing.                                    01218 (04C2h) USR 1218                      This is the SAVE  routine.  This  should  be  entered  with  DEholding the length of the block to save, IX  holding  the  startaddress, and the A register holding 0 for a "header " block,  or255 for a "program/data" block. The carry flag  should  also  beSET upon entry.                                                  This routine is called twice by the BASIC  SAVE  command,  oncefor the 17-byte header, and once more  for  the  main  block  ofdata.                                                            Incidentally, you can copy the ROM code into RAM, and alter thetimings to produce other SAVE speeds. The colours that are  usedfor the border during a SAVE ca n also be changed.                                                                                                   01366 (0556h) USR 1366                      Though this routine requires all the same registers to  be  setin exactly the same manner as for SAVE, there  are  quite  largedifferences between them.                                        LOAD,  can  to   a   certain   extent,   follow   quite   largeirregularities in the speed of the data coming in. It does  thisby detecting the edge, or  the  point,  when  the  signal  levelchanges, on each pulse                                           On return from the routine, the carry flag is set if  all  wentwell and reset if a loading error occured.                                       03282 (0CD2) THE SCROLL ROUTINE                 Unlike the ZX81, the Spectrum has no built-in SCROLL command toscroll the display with. This can be achieved  from  BASIC  withUSR 3282 which is the routine Mr Spectrum uses after it asks you"scroll?". This is the main entry  point;  see  later  for  someother, more interesting, ways to SCROLL.                                          03435 (0D68) THE CLS ROUTINE                   Maybe not much use from BASIC, because typing  CLS  is  easier,but this routine can be useful from machine code. The display iscleared to  the  current  attributes  (as  held  in  the  systemvariables) and various housekeeping functions are performed withchannel 'K'                                                      In  effect,  the  Spectrum  CLS   routine   is   un-necessarilycomplicated and slow. A faster and easier  way  to  do  this  isshown below:                                                             LD HL,16384 <Start of display file                              LD DE,16385 <Start+1                                            LD BC,6144 <Length of attributes                                LD (HL),L <Value to copy                                        LDIR <Clear it                                                  LD BC,792  This clears                                          LD A, <8 * paper + ink> > the attribtes                         LD (HL) ,A > Omit to leave                                      LDIR > colour intact                                   You can improve on  this  too,  but  that's  not  likely  to  benecessary in most applications.                                               03582 (0DFE) ANOTHER DISPLAY SCROLLER              Entering the routine at 3582 will scroll all 23  lines  of  thedisplay UP by  one  line.  Attributes  are  handled  also.  Thisroutine is called by USR 3282 itself.                            Entering the routine two bytes on,  you  can  select  a  bottomwindow to scroll. If you enter with the B register holding  say,10, then the subsequent CALLing of 3584 will scroll  the  bottomten lines up only, leaving  the  rest  of  the  display  on  topintact.                                                          This technique has been used in some adventures to  scroll  theinput lines, leaving the graphics intact.                                       03652 (0E44) CLEAR LINES ROUTINE                 This routine will clear the bottom 'x' lines of the screen, thevalue of 'x' being held in the B register. The area  is  clearedand filled with the current attribute values.                                 03756 (0EAC) ZX PRINTER COPY ROUTINE               Equivalent to the COPY command. One failing of COPY is that  itonly prints the top  22  lines  of  the  screen  and  completelyignores the bottom two lines. However,  the  routine  itself  isvery flexible, if used properly.                                 Just calling 0EAC directly will perform a straight screen  dumpbut, by calling a routine at 03762 (0EB2), it becomes much  moreinteresting.                                                     This is the routine called by USR 3756 (0EAC),  which  sets  upsome variables to perform a "standard" dump. You can create  thevariables yourself to produce some useful effects.                 DI <Vitally Important !                                         LD B,192 <The number of screen pixel lines to be copied.     The ROM sets this to 176, 22 * 8 pixel lines.  We  can  set  192lines for a full screen copy                                       LD HL,16384 < The Base address of the screen display.           CALL 0EB2 < Call the main routine.                            It would be possible to change the address loaded into  HL,  topoint to a screen that was stored elsewhere in the  memory.  Youcould thus COPY an invisible screen!                             This routine exits  via  ROM  routine  0EDF  which  clears  theprinter buffer. This is unnecessary, since the COPY routine doesnot use this area. If this bug had been  removed,  the  ZX  COPYcould have stiil worked on 128K machines. It is possible to  runa ZX or Alphacom printer on 128K  or  grey  +2  by  copying  theroutine, and removing the call to the routine  that  clears  thebuffer. Fireview 2's ZX routine does this.                       Here are the routines  used  to  print  via  the  buffer  area.Remember that these routines are only applicable to 48K mode.                   03789 (0ECD) COPY PRINTER BUFFER                 This routine will "copy" the contents  of  the  Printer  buffer(held at 23296) to the printer, logically. The routine exits via0EDF, which clears the buffer that runs from 23296 to 23551. Theroutine at 0EDF also resets the system variable  PR-CC  (PrinterColumn) to zero and resets bit one of FLAGZ to tell  the  systemthat the buffer is empty.                                        Perhaps you have wondered what it is that  enables  that  error"burp" sound?                                                                         04223 (10F7) ED ERROR                      This  piece  of  code  isn't  very  useful  but  it  is   quiteinteresting. It makes the buzz that a  ccompanies  errors  whileyou are editing. Filling up the screen with one line  or  tryingto edit lines with strange codes in cause it.                   10F7 BIT 4,(FLAGS2) No Buzz if not                                   JR Z,1026 using Channel K                                       LD (ERR-NR),FF Cancel Error                                     LD D,0 DE has length of                                         LD E,(RASP) buzz from sysvars.                                  LD HL,1A90 Note constant                                        CALL 03B5 Call the BEEPer                                                     04264 (10A8) KEYBOARD INPUT                   A reasonably useful routine which  returns  the  value  of  thecurrent key being pressed in the A register.  The  more  complexfeatures like CAPSLOCK PAPER and INK are also handled. The carryflag is SET when a key is found.                                                 04535 (11B7) THE 'NEW' ROUTINE                  This can be used from Basic or machine  code.  Typing  NEW  andenter is easier, however. System variables P-RAMT, RASP PIP  andUDG are left alone, as of is the value in  RAMTOP.  All  RAM  iscleared if below RAMTOP.                                         This routine is also called when the computer is turned  on  orreset with RANDOMISE USR 0, it enters the NEW routine  some  wayin, making it think that RAMTOP is at 65535 and that all RAM  isto be cleared and also that UDGs and system  variables  must  beset up, but we shall leave that until another day.                                     05808 (16B0) SETMIN                       It sets the edit area and all areas  after  it  (workspace  andcalculator stack) to their minimum values. The  apparent  effectis that these areas are "cleared".                                                     05861 (16E5) CLOSE#                       Entered with the A register holding the number of the stream tobe closed. This piece of code crashes the Speccy if you close  astream with a value of four or over, which has not been OPENed.  This is because no end  marker  is  on  the  look-up  table  at1716-171A. It had to  be  patched  by  a  hardware  addition  ininterface  1.  This  would  have  been  easy  to  fix  in  laterSpectrums, but it wasn't. It is for this reason  that  users  ofEDITOR who do not use drives  are  told  to  remove  the  CLOSE#statements.                                                                     06035 (1793) INTERFACE ONE ERROR                 Use of the commands CAT,  ERASE,  FORMAT  and  MOVE  takes  theSpeccy  here,  where  the  error  report  O  Invalid  Stream  isgenerated. However, if an interface one is present,  this  erroris detected and used to "wake up" the IF1 so that  it  gets  theidea that it has to perform a command. In the end, you never seethe error, since IF1 nullifies it as soon  as  it  happens,  andthen executes the required command.                                              06229 (1855) LIST A BASIC LINE                  This routine is entered with HL holding the address  in  memoryof where the line actually starts. Basic always  starts  at  theaddress found by PEEK 23635+256* PEEK 23636. This  is  the  PROGsystem variable. There is a similar one which gives the start ofthe next line.                                                                  06683 (1A1B) LINE NUMBER PRINTING                This prints a line numb er. It's entered with  BC  holding  thenumber to be printed. Be warned that numbers over 9999 will  notbe printed correctly.                                                        06747 (1A5B) PRINT a NUMBER TO A STREAM             It prints no leading spaces. If you REALLY want these, so  thatall numbers are padded out with spaces, then you may  enter  theroutine at 1A28. HL must point to the address where  the  numberyou require to print is stored. This example prints 2500 to  thecurrent stream.                                                       LD BC,2500                                                      CALL 1A5Bh                                                The alternative routine looks like this.                              LD HL,Any memory Location                                       LD BC,2500                                                      LD (HL),BC                                                      CALL 1A28h                                                This prints the leading spaces as I described.                                 08855 (2297h) BORDER COLOUR CHANGE                This routine should be entered with the border colour, (0-7) inthe A register. It will change the border  colour  and  set  theBORDCR system variable to the appropriate value. This is done sothe border colour does not change if  the  speaker  is  used.  Acontrasting INK is also set for the two input lines.                     4 ( 22AAh) PIXEL ADDRESS ROUTINE                        Used  by  both  POINT  and  PLOT,  it  is  entered   with   theco-ordinates of a screen pixel in BC. B holds the value for 'y',and C the value for 'x'.                                         On exit, the HL register pair contains the address of the  bytecontaining the pixel, and  the  A  register  holds  the  pixel'sposition within the byte.                                                          08911 (22CF) POINT ROUTINE                    This routine must be entered with the pixel position placed in the BC register pair, exactly as detailed on the previous page.  The value which would normally be given from the POINT  command- in the form 0=  paper,  and  1=  ink  -  is  pushed  onto  thecalculator stack. To retrieve it, you would  need  to  call  theroutine STK-TO-A at address 2314H. It would then  be  placed  inthe A register.                                                                    08927 (22DFh) PLOT ROUTINE                    Once again, the entry is made with the BC register pair holdingthe position of the  pixel  to  be  PLOTted.  The  rest  happensautomatically. The status of both INVERSE  and  OVER  are  takeninto account, as stored in the system variable P-FLAG at 23697.                     08967 (2307h) STACK TO BC                    This routine simply pulls a 16  bit  value  from  the  floatingpoint stack, and places it in the BC register pair.                                 08980 (2314h) STACK TO A                     As mentioned earlier, this can be used at any time to  take  an8-bit value from the floating point stack, and place it into theA register.                                                                          11400 (2C88h) ALPHANUM                      Now this is actually useful! It is entered with a value in  theA register, and if it is a valid ASCII code for a  letter  or  anumber, the carry flag is set. If it is not a valid  code,  thenthe carry flag is reset. There are two other routines with  verysinilar uses, these are:                                                              11547 (2D1Bh) N UMBER                      Only detects valid digits.                                                            11405 (2C8Dh) ALPHA                       This only checks for valid letters                                                  12457 (30A9h) MULTIPLY                      This has its uses too. It multiplies  HL  and  DE.  The  resultappears in the HL  register  pair.  However,  if  there  was  anoverflow, the carry flag is set.                                  That concludes this brief journey into the  Spectrum  ROM.  Inthese articles, I've only scratched  the  surface  of  the  mostuseful routines. The floating point calculator alone could  havea book written about it!                                          If this has aroused your  interest  in  the  workings  of  theSpectrum Rom,  the  only  book  that  I  can  reccomend  is  thelegendary SPECTRUM ROM DISASSEMBLY by DR IAN LOGAN  &  DR  FRANKO'HARA.                                                          It is, like many Spectrum titles, out of print now though.  ItsISBN number is 0-86161-116-0. You may find that Prestel Booklink(*BOOKLINK_) may be of use in locating a copy.