Changes

Jump to: navigation, search

NC 100/150/200 IO Specification

52,847 bytes removed, 20:38, 15 September 2010
 
This update to NCIOSPEC.TXT covers the differences between the NC100 hardware
(documented in the original NCIOSPEC.TXT below) and the NC200 hardware.
has a different clock speed.
Address Comment R/W ======= ======= ===
00 Display Memory start W 20 Memory card wait state W A0 Card Battery status R 60 Interrupt Request Mask W 70 on/off control W 80 Printer Status R 90 IRQ Status R B0-B9 Key data in R D0-D1 MC146818 Real Time Clock R/W E0 NEC765 Status R E1 NEC765 Data R/W
Address = 00 Write only
start address of display memory
----------------------------------------------------------
bit 7 A15
Address = 20 Write only
Memory card wait state control
----------------------------------------------------------
bit 7: memory card wait state control: 1 for wait states, 0 for no wait
Address = 70
on/off control
----------------------------------------------------------------
bit 2: Backlight: 1=off, 0=on
Address = A0
Card battery status
----------------------------------------------------------------
bit 7: memory card present 0 = yes, 1 = no
Address = B0 - B9 Read only
Keyboard data
-----------------------------------------------------------
B0..B9 each key of the 64 on the keyboard
Address = 60 Write only
Interrupt request mask
----------------------------------------------------------
bit 7: ** unknown use **
Address = 80
Printer status
----------------------------------------------------------
bit 7..1: * unknown use *
bit 0: printer busy status
Address = 90 Read/Write
IRQ status
-----------------------------------------------------------
bit 7: ** unknown use **
Address = D0/D1
MC146818 Real Time Clock
----------------------------------------------------------
Consult MC146818 datasheet.
Address = E0/E1
NEC765 floppy disc controller
----------------------------------------------------------
Consult NEC765 datasheet.
---Kev Thacker    Original NCIOSPEC.TXT follows: The following notes describe the low level operation of the Amstrad Notepadcomputers. They are intended for third party developers who want to programthe Notepad in machine code. As always, I will try to help out if anyone has questions about this but Icannot give an absolute guarantee to be able to provide support on the lowlevel operation of the machine. It is our intention that these firmware routines and system variables shouldbe maintained in future issues of the software but we cannot give an absoluteguarantee about this. Cliff Lawson CIS: 75300,1517Notepad project manager email: cliffl@amstrad.comAmstrad Plc amstrad@cix.compulink.co.uk169 Kings Road Phone: (+44) 277 208341Brentwood Fax: (+44) 277 208065EssexCM14 4EFENGLAND   I/O [[NC100 IO Specification for Amstrad NC100 <<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>> All numbers are in hexadecimal unless suffixed with a "b" for binary or"d" for decimal. (Address line numbers A19, A18, etc are in decimal).  SUMMARY ======= Address Comment R/W======= ======= === E0-FF Not Used -D0-DF RTC (TC8521) R/WC0-C1 UART (uPD71051) R/WB0-B9 Key data in RA0 Card Status etc. R90 IRQ request status R/W80-8F Not Used70 Power on/off control W60 IRQ Mask W50-53 Speaker frequency W40 Parallel port data W30 Baud rate etc. W20 Card wiat control W10-13 Memory management R/W00 Display memory start W   In Detail ========= Address = 00 Write onlystart address of display memory----------------------------------------------------------  bit 7 A15 bit 6 A14 bit 5 A13 bit 4 A12 bits 3-0 Not Used On reset this is set to 0. The display memory for the 8 line NC computers consists of a block of 4096bytes where the first byte defines the state of the pixels in the top lefthand corner of the screen. A 1 bit set means the pixel is set to black. Thefirst byte controls the first 8 dots with bit 7 controlling the bit on theleft. The next 59 bytes complete the first raster line of 480 dots. The byteswhich define the second raster line start at byte 64 to make the hardwaresimpler so bytes 60, 61, 62 and 63 are wasted. There are then another 64 bytes(with the last 4 unused) which defines the second raster line and so onstraight down the screen. That is (all numbers decimal):  byte00 byte01 byte02 byte60 byte61 byte63Bit Number 76543210 76543210 76543210 .. 76543210 76543210.. 76543210 Pixel Number 01234567 89012345 67890123 .. 23456789 wasted .. wasted(read bottom 00000000 00111111 11112222 77777777to top decimal) 00000000 00000000 00000000 44444444 ....and so on for subsequent lines. (Second line = bytes 64..127 etc.)  Address = 10..13 Read/WriteMemory management control--------------------------------------------------------  10 controls 0000-3FFF 11 controls 4000-7FFF 12 controls 8000-BFFF 13 controls C000-FFFF On reset all are set to 0. For each address the byte written has the following meaning:  bit 7 together they select ROM, internal RAM, card RAM bit 6 00b = ROM 01b = internal RAM 10b = card RAM  bits 5-0 determine address lines 19 to 14. Therefore, 00 is the first 16K of ROM, 01 is the second 16K, etc. 40 is the first 16K of internal RAM, 41=second 16K, etc. 80 is the first 16K of card RAM, 81=second 16K, etc. So, for example, if you want to switch the third 16K of internal RAM so theprocessor sees it at 4000-7FFF you would output the value 42 to I/O address11. 42 has bits 7,6 = 01b and bits 5-0 are 00010b which is the third 16K ofinternal RAM.  Address = 20 Write onlyMemory card wait state control----------------------------------------------------------  bit 7 = 1 for wait states, 0 for no wait On reset this is set to 1. The bit should be set if the card RAM/ROM is200nS or slower.  Address = 30 Write onlyBaud rate etc.----------------------------------------------------------  bit 7 select card register 1=common, 0=attribute bit 6 parallel interface Strobe signal bit 5 Not Used bit 4 uPD4711 line driver, 1=off, 0=on bit 3 UART clock and reset, 1=off, 0=on  bits 2-0 set the baud rate as follows  000 = 150 001 = 300 010 = 600 011 = 1200 100 = 2400 101 = 4800 110 = 9600 111 = 19200 On reset all data is set to 1. If programming the UART directly ensure that TxD clock is operating x16. Address = 40 Write onlyParallel interface data---------------------------------------------------------- The byte written here is latched into the parallel port output register. Toprint it you must then take the Strobe signal (I/O address 30 bit 6) low andthen high again. If the printer sends ACK this may generate an IRQ if the maskbit is set in I/O address 60 - IRQ mask. Address = 50..53 Write onlySound channels period control----------------------------------------------------------  50 channel A period low 51 channel A period high  52 channel B period low 53 channel B period high On reset all data is set to FF. The top bit in the high byte (51 and 53)switches the resepective sound generator on or off - 1=off, 0=on. The frequency generated is determined as:  Frequency = 1,000,000d ---------- data * 2 * 1.6276 So if the data word programmed into 50 and 51 was 7800 (ie 50=0, 51=78) thenthe frequency generated would be:  freq = 1,000,000 = 1,000,000 = 1,000,000 = 10Hz --------- --------- --------- 7800h * 2 * 1.6276 30720 * 2 * 1.6276 99,999.7  Address = 60 Write onlyInterrupt request mask----------------------------------------------------------  bits 7-4 Not Used bit 3 Key Scan interrupt (every 10mS) bit 2 ACK from parallel interface bit 1 Tx Ready from UART bit 0 Rx Ready from UART On reset all bits are 0. For each bit, 1=allow that interrupt source toproduce IRQs. 0 = interrupt source is masked. Address = 70 Write onlyPower off control----------------------------------------------------------  bits 7-1 Not Used bit 0 1 = no effect, 0 = power off On reset this is set to 1. Address = 90 Read/WriteIRQ status-----------------------------------------------------------  bits 7-4 Not Used bit 3 Key scan bit 2 ACK from parallel interface bit 1 Tx Ready interrupt bit 0 Rx Ready interrupt When an interrupt occurs this port should be read to determine the source ofthe interrupt. The bit will be set to 0 to identify the interrupting device.The interrupt can then be cleared by writing 0 to that bit. Address = A0 Read onlyMemory card/battery status----------------------------------------------------------  bit 7 Memory card present 0 = yes, 1 = no bit 6 Card write protected 1 = yes, 0 = no  bit 5 Input voltage = 1 if >= to 4 Volts bit 4 Mem card battery. 0 = battery is low bit 3 Alkaline batteries. 0 if >= 3.2 Volts bit 2 Lithium battery. 0 if >= 2.7 Volts  bit 1 Parallel interface BUSY (0 if busy) bit 0 Parallel interface ACK (1 if ACK)  Address = B0 - B9 Read onlyKeyboard data-----------------------------------------------------------  B0..B9 each key of the 64 on the keyboard will set a bit in one of these bytes while pressed. The gate array scans the keyboard every 10mS and then generates aninterrupt. The program should then read these 10 I/O locations todetermine which key(s) is pushed. When I/O address B9 is read thekey scan interrupt is cleared automatically and the next scan cyclewill start from B0. Address = C0 Read/WriteUART control/data------------------------------------------------------------  C0 UART data register C1 UART status/control register The UART is the NEC uPD71051. Programmers are advised to study the datasheet for that chip for more information. The Serial interface requiresthat the uPD4711 line driver chip be truned on by writing a 0 to bit 4 ofI/O address 30. While turned on power consumption increases so this shouldonly be done when necessary. Address = D0 Read/WriteReal Time Clock chip (TM8521)----------------------------------------------------------  D0..DC Data DD Control register DE Control register (Write only) DF Control register (Write only) See data sheet of chip for more information. =================================================================  NC100 operating system firmware <<<<<<<<<<<<<<<<>>>>>>>>>>>>>>> notes for external program writers================================== To get external programs executed on the Notepad you could either POKEthem into memory in BBC BASIC (or even use its built-in Z80 assembler)and then CALL the entry point. However, this does have the drawback ofneeding to transfer the code back to the machine each time it crashes(as it inevitably will). The simplest way to develop for the Notepad is to get a PCMCIA drivefor your PC and write a binary image direct to the card using that. Ifthis isn't possible then small programs (up to 16K) can be developed bytransferring the binary card image into the Notepad using Xmodem fromthe PC. The use the "Make program card" feature in the File, transfermenu to write that file onto a newly formatted PCMCIA RAM card. In either case, to run the resultant code, you just press Function-X(eXecute) and the first 16K page of the RAM card will be switched tothe Z80 memory map at C000..FFFF. A Check is made that location C200holds the ASCII text "NC100PRG" and also that locations C210..C212contains a long jump to C220. All being well, the Z80 starts executingcode at C210 so that, once you have control, you can take overcompletely if you wish (driving all hardware functions directly). Mostpeople will probably want to cooperate with the in built firmware as itprovides most of the routines that one would require anyway.  The ASCII text "NC100PRG" must appear at C200hprogram origin is C210hprogram MUST start with jp C220hthe program name is at C213h, max 12 characters, zero terminated  org C200h db "NC100PRG" org c210h jp start db "PROGRAM NAME",0 org C220h start available workspace A000h to A3FFh (shared with other programs)also A800h to AFFFh (this is overwritten if selectfile is called)the program MUST handle yellow events :- either exit when Stop is pressed or check for yellow event with kmgetyellow and return if carry set Serious developers may be interested in contacting Ranger Computers Ltdon (+44) 604 589200 as they can produce a device that looks like RAM toa PC but ends in a PCMCIA header plug that connects directly to theNotepad's card slot and the "PC RAM" appears as card RAM to the Notepad.  The following sequence is a working(!) piece of code written for theAVMACZ80 assembler on a PC, which, when assmembled produces a binaryfile that can be programmed onto a PCMCIA card and executed. Theprogram just reads keys and prints them back until "Q" is pressed. Notice that exit from the program is just by a RET back to theoperating system that called it: ;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV  include "nc100jmp.inc" ;The list of firmware routine ;addresses given later in this ;file   DEFSEG Fred, CLASS=CODE, START=0  SEG Fred ;Seg will be linked to RUNSAT C000h  jp start ;put a jump at the start in case this code is ;ever programmed into a ROM page where the entry ;will almost certainly be made at the more ;normal C000. ds 509 ;waste first 512 bytes of card to start at C200;; following 16 bytes are Arnor's header for card at C200; db "NC100PRG",0,0,0,0,0,3,0,1;; then card program must start with this long jump at C210; jp start ;this is at C210h db "CLIFFS PROG",0,0 ;0's pad to C220h start: call kmreadchar ld a,c cp "q" jr z,finish call txtoutput jr start finish: ret  end ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; code is assembled with:; AVMACZ80 TEST.ASM;which produces a .OBJ file which is then linked to produce a .HEX file;with the command; AVLINK @TEST.LNK;where TEST.LNK contains:; TEST.HEX=TEST.OBJ -RUNSAT(Fred, 0C000h);finally the Intel .HEX file is converted to .BIN using a HEX2BIN converter;The .BIN file is either written to the PCMCIA card using a PC based;card drive or it can be Xmodemed across to the Notepad and written to;the card using "Make program card". Finally, Function-X executes it. In other assemblers you may not have "segments" and must use a directORG to locate code at C000 but watch out for the resultant .HEX filebeing padded out with 48K of "0"s from 0000 to BFFF!!  Alphabetic list of routine entry points======================================= To use any one of these routines just load the registers as described inthe following and then call the relevant address. Although the running of theroutine may involve a different ROM bank being switched in, this mechanismis invisble to the caller. So, for example, to print a capital A one might use: txtoutput EQU B833 LD A,"A" CALL txtoutput col1 equ B818hcol1text equ B81Bhdiskservice equ BA5Eheditbuf equ B800hfclose equ B890hfdatestamp equ B8C9hferase equ B893hfgetattr equ B8CFhfinblock equ B896hfinchar equ B899hfindfirst equ B89Chfindnext equ B89Fhfnoisy equ B917hfopenin equ B8A2hfopenout equ B8A5hfopenup equ B8A8hfoutblock equ B8ABhfoutchar equ B8AEhfquiet equ B91Ahfrename equ B8B1hfseek equ B8B4hfsetattr equ B8CChfsize equ B8B7hfsizehandle equ B8BAhftell equ B8BDhftesteof equ B8C0hheapaddress equ B87Ehheapalloc equ B881hheapfree equ B884hheaplock equ B887hheapmaxfree equ B88Ahheaprealloc equ B88Dhkmcharreturn equ B803hkmgetyellow equ B8D2hkmreadkbd equ B806hkmreadchar equ B9B3hkmsetexpand equ B809hkmsettickcount equ B80Chkmsetyellow equ B8D5hkmwaitkbd equ B80Fhlapcat_receive equ B8D8hlapcat_send equ B8DBhmcprintchar equ B851hmcreadyprinter equ B854hmcsetprinter equ B857hpadgetticker equ B872hpadgettime equ B875hpadgetversion equ B8DEhpadinitprinter equ BA4Fhpadinitserial equ B85Ahpadinserial equ B85Dhpadoutparallel equ B860hpadoutserial equ B863hpadreadyparallel equ B866hpadreadyserial equ B869hpadresetserial equ B86Chpadserialwaiting equ B86Fhpadsetalarm equ B878hpadsettime equ B87Bhpagemodeon equ BA49hpagemodeoff equ BA4Chreadbuf equ B812hselectfile equ B8C3hsetdta equ B8C6htestescape equ B815htextout equ B81Ehtextoutcount equ B821htxtboldoff equ B83Fhtxtboldon equ B842htxtclearwindow equ B824htxtcuroff equ B827htxtcuron equ B82Ahtxtgetcursor equ B82Dhtxtgetwindow equ B830htxtinverseoff equ B845htxtinverseon equ B848htxtoutput equ B833htxtsetcursor equ B836htxtsetwindow equ B839htxtunderlineoff equ B84Bhtxtunderlineon equ B84Ehtxtwrchar equ B83Ch   Notepad memory map ================== 16K code/data sections always mapped to C000hÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄ¿³ video RAM ³ ³Protext ³Dictionary³Con-³Calc³Addr³Diary³ BBC ³³---------------³ ³ ³ data ³trol³ ³book³ ³BASIC ³³ RAM ³ ³ 1 & 2 ³ 6 blocks ³ ³ ³ ³ ³ ³ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ C000 ÀÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÙ³stack/variables³ \³---------------³ B000 | common RAM (accessible by all programs)³ RAM ³ /ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ 8000 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿³ ³ ³ ³³ RAM ³ ³ PLS ³³ ³ ³ ³ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ 4000 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ spell ³³ ³ ³OS- remaps high³ ³ checking ³³ RAM ³ ³---------------³ ³ code ³³ ³ ³ Startup code ³ ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ 0 ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ  general notes: most routines return carry set if successful unless otherwise stated assume AF corrupted, other regs preserved "all registers preserved" includes flags, but NOT alternate registers the ALTERNATE register contents can NEVER be assumed to be preserved (they are used as scratch registers in time critical routines)  ==============editbuf = B800============== line editor with options zero-terminated string may be passed in buffer (HL) this will display the initial contents ENTRY - HL : pointer to input buffer B : size of buffer (excluding terminating zero) A : flags. b2=1 -> �� terminate entry b3=1 -> input not echoed b6=1 -> dotty background (character 176) b5=1 -> edit unless characters entered b4=1 -> delete trailing spaces Other bits must be set to zero. EXIT - c=0 z=1 ESC pressed c=1 z=1 empty string input c=1 z=0 at least one character entered HL preserved BC = last key token (or -1 if ESC used to terminate) ===================kmcharreturn = B803=================== returns a token to the keyboard buffer ENTRY - BC = the token EXIT - all registers preserved ================kmreadkbd = B806================ Gets a key token if there is one, does not wait (Checks put back character and expands macros) Returns tick event tokens if enabled ENTRY - none EXIT c=1 : BC = token (B=0 for simple character) c=0 : no key token available =================kmreadchar = B9B3================= This routine is the same as kmreadkbd but macros are exapnded and one or two other "behind the scenes" tasks are performed. By using this routine you can be sure that the Ctrl+Shift+S screen dump mechanism works in your code ==================kmsetexpand = B809================== Defines a macro string ENTRY - BC = macro token (between 256 and 383) - HL points to new macro string (first byte is the length, followed by the string - need not be zero terminated) EXIT - c=1 if macro defined successfully c=0 if insufficient room in buffer (The buffer size is user configurable) =====================kmsettickcount = B80C===================== Enables the ticker event There are 100 ticks per second When a ticker event occurs t.tickevent is returned by kmreadkbd ENTRY - HL : number of ticks before first event DE : number of ticks between events EXIT - all registers preserved ================kmwaitkbd = B80F================ Waits for a key token, uses kmreadkbd (Checks put back character and expands macros) Returns tick event tokens if enabled ENTRY - none EXIT c=1 : BC = token (B=0 for simple character) ==============readbuf = B812============== line editor. See also editbuf. ENTRY - HL : pointer to input buffer (empty) B : size of buffer (excluding terminating zero)  EXIT - c=0 z=1 ESC pressed c=1 z=1 empty string input c=1 z=0 at least one character entered HL preserved BC = last key token (or -1 if ESC used to terminate) =================testescape = B815================= tests whether an ESC key has been pressed (STOP or FUNCTION) waits for a key if one is found in the keyboard buffer ENTRY - none EXIT - c=1 if no ESC key in buffer c=1 if ESC key in buffer but STOP not pressed c=0 if ESC key in buffer and STOP then pressed A is preserved ===========col1 = B818=========== if cursor is at start of a line do nothing otherwise move cursor to start of next line (within window) ENTRY - none EXIT - none ===============col1text = B81B=============== same as textout, but calls col1 first ==============textout = B81E============== displays string ENTRY - HL : pointer to zero-terminated string *************************************************************** WARNING - HL must not point into an upper ROM! *************************************************************** EXIT - none ===================textoutcount = B821=================== as textout, returns character count in B =====================txtclearwindow = B824===================== clears current window and moves cursor to top left ================txtcuroff = B827================ removes the cursor from the screen ENTRY - none EXIT - all registers preserved ===============txtcuron = B82A=============== displays the cursor on the screen ENTRY - none EXIT - all registers preserved ===================txtgetcursor = B82D=================== returns the cursor position ENTRY - none EXIT - H = column (between 0 and 79) L = row (between 0 and 7)===================txtgetwindow = B830=================== returns the window coordinates ENTRY - none EXIT - H = left column (between 0 and 79) L = top row (between 0 and 7) D = right column (between 0 and 79) E = bottom row (between 0 and 7) c=0 if window is whole screen c=1 if a smaller window has been ================txtoutput = B833================ displays a character or acts on control code ENTRY - A = character A=7 : beeps A=10 : LF A=13 : CR All other values displayed as character (PC char. set) EXIT - all registers preserved ===================txtsetcursor = B836=================== moves the cursor ENTRY - H = column (between 0 and 79) L = row (between 0 and 7) EXIT - none ===================txtsetwindow = B839=================== defines a new window ENTRY - H = left column (between 0 and 79) L = top row (between 0 and 7) D = right column (between 0 and 79) E = bottom row (between 0 and 7) EXIT - none ================txtwrchar = B83C================ displays a character ENTRY - A = character. All values displayed (PC char. set) EXIT - all registers preserved ======================txtboldoff = B83Ftxtboldon = B842txtinverseoff = B845txtinverseon = B848txtunderlineoff = B84Btxtunderlineon = B84E====================== These six routines enable or disable various display attributes. They have no entry conditions and preserve all registers. ==================mcprintchar = B851================== sends a character to the printer ENTRY - A=character EXIT - c=1 if successful c=0 if not sent A preserved =====================mcreadyprinter = B854===================== tests whether the printer is ready ENTRY - none EXIT - c=0 if busy c=1 if ready A preserved ===================mcsetprinter = B857=================== sets the printer type to be used by mcprintchar and mcreadyprinter ENTRY - A=printer type, 0=parallel, 1=serial EXIT - none ====================padinitserial = B85A==================== initialises the serial port using the global configured settings turns on the UART and 4711 do not call this until needed - to prolong battery life ENTRY - none EXIT - none ==================padinserial = B85D================== reads a character from the serial port ENTRY - none EXIT - c=1 if successful, A=character c=0 if no character read =====================padoutparallel = B806===================== sends a character to the parallel port ENTRY - A=character EXIT - c=1 if successful c=0 if not sent A preserved ===================padoutserial = B863=================== sends a character to the serial port ENTRY - A=character EXIT - c=1 if successful c=0 if not sent A preserved =======================padreadyparallel = B866======================= tests whether the parallel port is ready ENTRY - none EXIT - c=0 if busy c=1 if ready A preserved =====================padreadyserial = B869===================== tests whether the serial port is ready ENTRY - none EXIT - c=0 if busy c=1 if ready A preserved =====================padresetserial = B86C===================== turns off the UART and 4711 call this when finished using the serial port to prolong battery life ENTRY - none EXIT - none =======================padserialwaiting = B86F======================= tests whether there is a character waiting to be read from the serial port ENTRY - none EXIT - c=1 if character waiting c=0 if no character waiting ===================padgetticker = B872=================== returns the address of a 4 byte 100Hz ticker ENTRY - none EXIT - HL is the address of the least significant byte =================padgettime = B875================= reads the time and date from the RTC ENTRY - HL points to an 7 byte buffer to use EXIT - HL preserved data returned as above (see padsettime) ==================padsetalarm = B878================== sets the ALARM date and time (within next month) ENTRY - HL points to 3 byte data area byte 0=date 1=hour 2=minute EXIT - none =================padsettime = B87B================= sets the RTC date and time ENTRY - HL points to 7 byte data area bytes 0,1 = year (low,high) 2=month 3=date 4=hour 5=minute 6=second EXIT - none ==================heapaddress = B87E================== obtains the address of a memory block for a given memory handle ENTRY - DE = memory handle EXIT - HL = pointer to memory block ================heapalloc = B881================ allocates a block of memory from the heap ENTRY - DE = number of bytes to allocate EXIT - HL = memory handle in range [1,63] if successful HL = 0 if failed Note: heapaddress must be used to get a pointer to the memory block Unless the block is locked with heaplock, heapaddress must be called each time the memory block is used. IT MAY HAVE MOVED! ===============heapfree = B884=============== frees a block of memory ENTRY - DE = memory handle, returned by heapalloc or heaprealloc EXIT - none (preserves HL,BC) Note: the memory handle passed must be a valid handle returned by heapalloc or heaprealloc. This is not validated. ===============heaplock = B887=============== locks or unlocks a memory block ENTRY - DE = memory handle BC = non zero - the block is locked. It will not be moved until unlocked so fixed addresses can be used as pointers into the block BC = 0 - the block is unlocked ==================heapmaxfree = B88A================== returns the largest block size that can be allocated ENTRY - none EXIT - HL = largest free block size in bytes ==================heaprealloc = B88D================== changes the size of an allocated memory block ENTRY - DE = memory handle BC = new size for memory block EXIT HL = zero if failed to reallocate The old block will not be freed but could have moved HL = non-zero if successful Note: if the block is being expanded, it must be assumed that the base of the memory block will be moved (even if the block cannot actually be expanded) so heapaddress must be called afterwards. If the block is being contracted, the base will not move. =============fclose = B890============= closes a file ENTRY - DE = file handle EXIT - c=1 if successful, c=0 if failed =============ferase = B893============= erases a file ENTRY - HL = zero-terminated filename EXIT - c=1 if OK, c=0 if error (file not found) ===============finblock = B896=============== reads a block from a file ENTRY - DE = file handle - HL = buffer - BC = number of bytes to read (> 0) EXIT - c=1 if end of file not reached - c=0 if eof (or error?) - BC = number of bytes read - HL = address after last byte read KNOWN BUG (1.00,1.01) - finblock does not set the file position so repeated calls will always read from the start of the file Workaround: call fseek after calling finblock to set the pointer ============finchar B899============ reads a byte from a file ENTRY - DE = file handle EXIT - c=1 if successful, A=character c=0, A corrupt if end of file reached other regs preserved ================findfirst = B89C================ finds first file. setdta must have been called first ENTRY - none EXIT - HL=0 if no files - HL points to file info structure if file found - 1st item in structure is the filename, zero-terminated - (up to 12 characters long) - offset 13 is attribute byte - offset 14/15 is the file size in bytes ===============findnext = B89F=============== finds next file. findfirst must have been called first ENTRY - none EXIT - HL=0 if no more files - HL as findfirst if file found ==============fopenin = B8A2============== opens a file for input ENTRY - HL points to zero-terminated filename EXIT - c=1 if successful, DE=file handle c=0 if failed (file not found) DE corrupt if error A corrupt, other regs preserved ===============fopenout = B8A5=============== opens a file for output ENTRY - HL points to zero-terminated filename EXIT - c=1 if successful, DE=file handle c=0 if failed (out of memory/too many files/file exists) DE corrupt if error A corrupt, other regs preserved ==============fopenup = B8A8============== opens a file for input and output. the file must exist already ENTRY - HL points to zero-terminated filename EXIT - c=1 if successful, DE=file handle c=0 if file not found DE corrupt if error A corrupt, other regs preserved ================foutblock = B8AB================ writes a block to a file ENTRY - DE = file handle - HL = buffer - BC = number of bytes to write (> 0) EXIT - c=1 if OK - c=0 if error - BC = number of bytes written - HL = address after last byte written ===============foutchar = B8AE=============== writes a byte to a file ENTRY - DE = file handle - A = character EXIT - c=1 if successful c=0, A corrupt if end of file reached A corrupt, other regs preserved ==============frename = B8B1============== renames a file ENTRY - HL = zero-terminated old filename - DE = zero-terminated new filename EXIT - c=1 if OK, c=0 if error (file not found) ============fseek = B8B4============ moves the file pointer to a position within a file ENTRY - DE = file handle - BC = offset from start of file EXIT - c=1 if successful c=0 if offset past end of file (pointer not changed) KNOWN BUG (1.00,1.01) - leaves error messages enabled (fnoisy) Workaround: call fquiet after fopenout if necessary ============fsize = B8B7============ finds size of file ENTRY - HL = zero-terminated filename EXIT - c=1 HL=size in bytes, if found - c=0 if not found ==================fsizehandle = B8BA================== finds size of an open file ENTRY - DE = file handle EXIT - HL=size in bytes ============ftell = B8BD============ returns the value of the file pointer ENTRY - DE = file handle EXIT - HL = current file position ===============ftesteof = B8C0=============== tests whether end of file has been reached ENTRY - DE=file handle EXIT - c=1 if not eof, c=0 if eof =================selectfile = B8C3================= displays the file selector (clears the screen first) shows all files and allows a selection to be made using the cursor keys and RETURN ENTRY - none EXIT - c=1 if a file selected (RETURN pressed) HL = filename - c=0 if STOP pressed =============setdta = B8C6============= set memory block to be used by findfirst/findnext ENTRY - DE= address of buffer (at least 35 bytes long) buffer must be in common RAM (8000h-BFFFh) EXIT - none =================fdatestamp = B8C9================= sets file date/time to current date/time ENTRY - HL = zero terminated filename EXIT - c=1 if successful - c=0 if not found ===============fsetattr = B8CC=============== sets the attribute byte for a file open for output if the file is open for input only there is no effect ENTRY - DE = file handle - C = attribute byte bit 0 = system file bit 1 = hidden file bit 2 = BASIC program bit 3 = binary file EXIT - c=1 if successful - c=0 if not found ===============fgetattr = B8CF=============== returns attribute byte of file ENTRY - HL = zero-terminated filename EXIT - c=1 A=attribute, if found - c=0 if not found preserves HL ==================kmgetyellow = B8D2================== ascertains whether a 'yellow event' is pending (so called because the FUNCTION key is coloured yellow) a yellow event occurs (i) when the user has pressed one of the the FUNCTION+key combinations that cause an immediate context switch (FN+red, FN+green, FN+blue, FN+menu) or (ii) when the machine is powered up and (because the option to preserve context has not been set) needs to return to the main menu  ENTRY - none EXIT - c=1, BC=token if yellow event pending An application should exit normally as quickly as possible Any UNSAVED FILES should be SAVED AUTOMATICALLY! - c=0, BC=0 if no yellow event pending  Note: each of the yellow event keys return the ESC token (2FCh) An application should call kmgetyellow whenever an ESC is read, this distinguishes between a yellow event and an ordinary ESC. ==================kmsetyellow = B8D5================== sets up a yellow event. Specialised use only. ENTRY - BC = a yellow event token EXIT - none =====================lapcat_receive = B8D8===================== reads a character from the parallel port using Lapcat protocol ENTRY - none EXIT - c=1 if successful, A=character c=0 if no character read ==================lapcat_send = B8DB================== sends a character to the parallel port using Lapcat protocol ENTRY - A=character EXIT - c=1 if successful c=0 if error ====================padgetversion = B8DE==================== gets the firmware version number  ENTRY - none EXIT - HL = version number (*100) Thus, 1.03 returns 103 ==================diskservice = BA5E================== calls a Ranger disk routine  ENTRY - C = number of routine to call A, HL, DE passed to the disk routine EXIT - c=1 if successful, HL may contain returned value c=0 if failed, A = error code (Ranger documentation)  C = 0 r_test 3 r_begin 6 r_change_disk 9 r_check_disk C r_get_cd F r_set_cd 12 r_set_dta 15 r_find_first 18 r_find_next 1B r_save_file 1E r_retrieve_file 21 r_set_attrib 24 r_create_directory 27 r_remove_directory 2A r_delete_file 2D r_rename_file 30 r_finish 33 r_disk_space 36 r_install 39 r_park_heads 3C r_format_track 3F r_format_done 42 r_save_wordstar 45 r_save_ascii 48 r_begin_program 4B r_load_program  System variables <<<<<<<<>>>>>>>> The following are the RAM based variables used by the operating system. Itis hoped that they will always use these locations in subsequent versionsof the software - but this is not guaranteed. B000 copyofmmu0 ds 1 ; copy of MMU0 since it's a write-only portB001 copyofmmu1 ds 1 ; copy of MMU1 since it's a write-only portB002 copyofmmu2 ds 1 ; copy of MMU2 since it's a write-only portB003 copyofmmu3 ds 1 ; copy of MMU3 since it's a write-only port B004 gotcontext ds 1B005 __savepearlmmu ds 1 ; extra vars needed in case we mustn't save contextB006 __saveaf ds 2B008 __savehl ds 2B00A saveaf ds 2 ; to save context, we need to save all the registers ...B00C savebc ds 2B00E savede ds 2B010 savehl ds 2B012 saveix ds 2B014 saveiy ds 2B016 savepc ds 2B018 savesp ds 2B01A saveafdash ds 2B01C savebcdash ds 2B01E savededash ds 2B020 savehldash ds 2B022 savemmu0 ds 1 ; ... and the memory stateB023 savemmu1 ds 1B024 savemmu2 ds 1B025 savemmu3 ds 1B026 savecritpc ds 2B028 savecritsp ds 2B02A savingcontext ds 1B02B nmimagic ds 4B02F nmichksums ds 8 ; checksum bytes of first 8 romsB037 criticalpc ds 2 ; save pc,sp for recovery from NMI during IRQB039 criticalsp ds 2 B03B ds 80 ; A small stack which we only use in initialisation. ; It can't sensibly overlap with anything in case we get an NMI ; requring immediate shut down after saving context. ; Subsequent power on will have to restore the contextB08B initstackB08B diagnostics? ds 1 ; flag used in start-up, nonzero to do diagnosticsB08C saveprinstat ds 1B08D kbdstate1 ds 10 ; 1 bit per key, 1=down 0=up corresponds to matrixB097 kbdstate2 ds 10 PADKEYBUFLEN equ 32 ; this MUST be 2^n for positive integer nB0A1 padkeybuf ds PADKEYBUFLEN*2 B0E1 padnextin ds 1 ; offset into padkeybufB0E2 padnextout ds 1B0E3 padbufempty ds 1 ; nonzero if emptyB0E4 lastkbdstate ds 2B0E6 thiskbdstate ds 2B0E8 caps.state ds 1 ; 0=off FF=onB0E9 savecaps ds 1B0EA justswitchedon? ds 1 ; variables above here are preserved after timeout PADSERBUFLEN equ 32 ; this MUST be 2^n for positive integer nB0EB padserbuf ds PADSERBUFLENB10B padsernextin ds 1B10C padsernextout ds 1B10D padserbufempty ds 1B10E padserin_xoff ds 1 ; non-zero when XOFF has stopped inward transmissionB10F padserout_xoff ds 1 ; non-zero when XOFF has stopped outward transmissionB110 disablexonxoff ds 1 ; nonzero to disable software handshake B111 ackirq ds 1 ; set non-zero when ACK interrupt occurs B112 rptdelay ds 1 ; centisecsB113 rptrate ds 1 ; centisecsB114 rpttimer ds 1 ; count down timer for key repeatB115 keytorepeat ds 1 ; key numberB116 rptkeystates ds 1 ; shift states B117 rtcbuf ds 13B124 d.alarmday ds 6 ; alarm day,hour,min ready for rtc chipB12A alarmhappened ds 1 ; non zero when alarm has gone off, message pendingB12B alarmhappenedgotmsg ds 1 ; non zero when alarm has gone off, got message & pendingB12C soundcounter ds 1 ; non-zero if we're playing a tuneB12D soundptr ds 2 ; pointer to array of frequency,durationB12F soundrepcount ds 1B130 soundrepptr ds 2B132 poweroffminutes ds 1 ; configured time to power offB133 minutesleft ds 1B134 minutecounter ds 2B136 eventhappened ds 1B137 preservecontext ds 1 ; 0=return to main screen at power onB138 dontpreservecontext ds 1 ; 1=dont preserve (diag/batt) B139 mainprog ds 1 ; 6=inbasic, 128=inexternal (foreground program id)B13A currentprinter ds 1 ; 0 for parallel, 1 for serialB13B currentmenu ds 2 ; pointer to current menuB13D wasmenusel ds 1 ; after kmwaitchar this is 1 if menu used, 0 if not ; need this in fsel to know whether redraw needed B13E lastsecond ds 1 ; checked to see whether to update the timeB13F clockon? ds 1 ; uses in Protext, non-zero when clock is enabled B140 sdumpname ds 4 ; s.a, s.b, s.c etc. for screen dump name ; force d.workspace to an 8 byte boundaryB148 d.workspace ds 8 ; for massaged copy of symbol data (eg inverse/underline) B150 d.datebuf ds 9+MAXMONTHLEN ; 27 January 1992B162 d.asciitime ds 12 ; hh:mm:ss xm\0 B16E currentcfg ds cfg.len B1BA g.outstream ds 1 ; bit 0 for screen, 1 for printer, 2 for fileB1BB g.h.outfile ds 2 ; file handle for charout if bit 2 setB1BD g.pos ds 1 ; current column number (charout) B1CE def.fname ds MAXPNLEN+1 ; Name of current file being edited ; first byte not zero if document open ; (yellow/red goes to edit mode, transfer from addrbook works)B1DD def.first ds 1 ; DO NOT CHANGE THE LAYOUT OF THE FIRST 21 BYTES 0024 len.findinfo equ 36 000D o.findinfo.attr equ 13 000E o.findinfo.size equ 14 0010 o.findinfo.time equ 16 0012 o.findinfo.date equ 18 0023 o.findinfo.mhandle equ 35 B1DE d.findinfobuf ds len.findinfo 0002 o.file.size equ 2 0005 o.file.mhandle equ 5 000D o.file.attr equ 13 000D o.direntry.attr equ 13 000E o.direntry.size equ 14 0010 o.direntry.time equ 16 0012 o.direntry.date equ 18 ; char name[13]; /* 12 chars plus \0 (the file we found) */; char attribute;; uint size; /* filesize can't be bigger than 64k */; uint time,date; /* if we allow time & date stamping */; char flags; /* memory block flags */; char handle; /* memory block handle */ ;****************************************************************************** ; PEARL.TXT DATA ;; The following 8 bytes are saved for each stream B202 d.thisstream ds 8-8B202 d.colrow ds 2-2 ; keep next 2 togetherB202 d.row ds 1 ; 0-based within windowB203 d.col ds 1 ; B204 d.winlefttop ds 2-2 ; keep next 2 togetherB204 d.wintop ds 1B205 d.winleft ds 1 B206 d.winsize ds 2-2 ; keep next 2 togetherB206 d.winheight ds 1 ; height -1B207 d.winwidth ds 1 ; width -1 B208 d.winset? ds 1 ; NZ if windowB209 d.state ds 1 ; bit 7 if inverse on ;; The following are recalculated from the above (in txtstrselect) B20A d.colrowcount ds 2-2 ; keep next 2 togetherB20A d.rowcount ds 1B20B d.colcount ds 1 ; how many more cols to print on this lineB20C d.stream ds 1 ; current stream numberB20D d.fastpos ds 2 ; needed for quick screen update B20F d.streamwsp ds 8*NSTREAMS ; 8 streams of 8 bytes each B24F d.dateptr ds 2 ; non null for expanding time/dateB251 d.kmcharret ds 2 ; Returned characterB253 d.kstate ds 2 ; Key locks stateB255 d.caslocks ds 1 ; Shift states set by sticky key pressB256 d.sticky ds 1 ; non-zero in sticky key modeB257 d.yellow ds 1 ; low byte of yellow/other key token ; stored by p.xlattoken which then returns ESCB258 d.calcmode ds 1 ; nonzero if keyboard in calculator mode B259 d.kmexplen ds 1 ; expansion string lengthB25A d.kmexpptr ds 2 ; expansion string pointerB25C d.expbuffer ds 2 ; address of expansion key bufferB25E d.expbufptr ds 2 ; pointer to free byteB260 d.expbufend ds 2 ; last byte in buffer B2A1 macro_buf ds 256 ; file selector variablesB3A7 fs_clicat ds 1 ; non-zero if CAT command, not fselB3A8 fs_showsizes ds 1 ; non-zero if showing file sizes (pad default=off)B3A9 fs_showsys ds 1 ; non-zero if showing system filesB3AA fs_curfile ds 1 ; current file number offset from top leftB3AB fs_topleftfile ds 1 ; file number displayed top leftB3AC fs_numcols ds 1B3AD fs_colwidth ds 1B3AE fs_numshown ds 1B3AF fs_maxfiles ds 1 ; max files that can be shownFS_NUMROWS .equ 7 ; display rowsFS_NUMCOLS .equ 5FS_COLWIDTH .equ 16B3B0 fs_handle ds 2FS_NUMSHOWN .equ FS_NUMCOLS*FS_NUMROWS ; number of files shownB3B2 fs_numfilerows ds 1 ; rows of files in CAT commandB3B3 fs_startlist ds 2 ; start of file list ; zero if doing unsorted listB3B5 fs_startdir ds 2 ; start of directory entriesB3B7 fs_endlist ds 2B3B9 fs_numfiles ds 1 ; number of files in directoryB3BA fs_lastshown ds 1 ; last filenumber currently shown ; fs_topleft + FS_NUMSHOWN B3BB tickcount ds 4 ; 32 bit counter needed for basicB3BF ticksleftuntilevent ds 2B3C1 tickreloadvalue ds 2B3C3 tickeventpending ds 1B3C4 countdowntimer ds 2 B3C6 savestream ds 1 B3C7 password ds 5 ; encryptedB3CC pwbuf ds 5 ; clearB3D1 realpwbuf ds 5 ; the real password saved for encryptingB3D6 haspassword ds 1 ; non-zero if has password ;passwdmsg ds 2B3D7 passwdlen ds 1B3D8 passwordlocked ds 1 ; non-zero if locked (disallow soft reset)B3D9 editingsecret ds 1 ; non-zero when editing secret file (can't delete it)B3DA inmenu? ds 1 ; non-zero when inside menu - macros disabled B3DB macro_count ds 1B3DC recording? ds 1B3DD macro_token ds 2 B3DF printfailed ds 1 ; flag set by mccheckprinter ; stops "finished printing" messageB3E0 wasmemoryerr ds 1B3E1 inprotext ds 1 ; used in file selector, 0=was Fn-L, nonzero=Fn-2 **** End ****
2,541
edits