|
|
| Line 1: |
Line 1: |
|
| |
| This update to NCIOSPEC.TXT covers the differences between the NC100 hardware | | This update to NCIOSPEC.TXT covers the differences between the NC100 hardware |
| (documented in the original NCIOSPEC.TXT below) and the NC200 hardware. | | (documented in the original NCIOSPEC.TXT below) and the NC200 hardware. |
| Line 30: |
Line 29: |
| has a different clock speed. | | has a different clock speed. |
|
| |
|
| Address Comment R/W | | Address Comment R/W |
| ======= ======= === | | ======= ======= === |
|
| |
|
| 00 Display Memory start W | | 00 Display Memory start W |
| 20 Memory card wait state W | | 20 Memory card wait state W |
| A0 Card Battery status R | | A0 Card Battery status R |
| 60 Interrupt Request Mask W | | 60 Interrupt Request Mask W |
| 70 on/off control W | | 70 on/off control W |
| 80 Printer Status R | | 80 Printer Status R |
| 90 IRQ Status R | | 90 IRQ Status R |
| B0-B9 Key data in R | | B0-B9 Key data in R |
| D0-D1 MC146818 Real Time Clock R/W | | D0-D1 MC146818 Real Time Clock R/W |
| E0 NEC765 Status R | | E0 NEC765 Status R |
| E1 NEC765 Data R/W | | E1 NEC765 Data R/W |
|
| |
|
|
| |
|
| Address = 00 Write only | | Address = 00 Write only |
| start address of display memory | | start address of display memory |
| ----------------------------------------------------------
| | |
|
| |
|
| bit 7 A15 | | bit 7 A15 |
| Line 57: |
Line 56: |
| Address = 20 Write only | | Address = 20 Write only |
| Memory card wait state control | | Memory card wait state control |
| ----------------------------------------------------------
| |
| | | |
| bit 7: memory card wait state control: 1 for wait states, 0 for no wait | | bit 7: memory card wait state control: 1 for wait states, 0 for no wait |
| Line 66: |
Line 64: |
| Address = 70 | | Address = 70 |
| on/off control | | on/off control |
| ----------------------------------------------------------------
| | |
|
| |
|
| bit 2: Backlight: 1=off, 0=on | | bit 2: Backlight: 1=off, 0=on |
| Line 74: |
Line 72: |
| Address = A0 | | Address = A0 |
| Card battery status | | Card battery status |
| ----------------------------------------------------------------
| | |
|
| |
|
| bit 7: memory card present 0 = yes, 1 = no | | bit 7: memory card present 0 = yes, 1 = no |
| Line 87: |
Line 85: |
| Address = B0 - B9 Read only | | Address = B0 - B9 Read only |
| Keyboard data | | Keyboard data |
| -----------------------------------------------------------
| | |
|
| |
|
| B0..B9 each key of the 64 on the keyboard | | B0..B9 each key of the 64 on the keyboard |
| Line 98: |
Line 96: |
| Address = 60 Write only | | Address = 60 Write only |
| Interrupt request mask | | Interrupt request mask |
| ----------------------------------------------------------
| | |
|
| |
|
| bit 7: ** unknown use ** | | bit 7: ** unknown use ** |
| Line 111: |
Line 109: |
| Address = 80 | | Address = 80 |
| Printer status | | Printer status |
| ----------------------------------------------------------
| | |
| bit 7..1: * unknown use * | | bit 7..1: * unknown use * |
| bit 0: printer busy status | | bit 0: printer busy status |
| Line 118: |
Line 116: |
| Address = 90 Read/Write | | Address = 90 Read/Write |
| IRQ status | | IRQ status |
| -----------------------------------------------------------
| | |
|
| |
|
| bit 7: ** unknown use ** | | bit 7: ** unknown use ** |
| Line 132: |
Line 130: |
| Address = D0/D1 | | Address = D0/D1 |
| MC146818 Real Time Clock | | MC146818 Real Time Clock |
| ----------------------------------------------------------
| | |
| Consult MC146818 datasheet. | | Consult MC146818 datasheet. |
|
| |
|
| Line 138: |
Line 136: |
| Address = E0/E1 | | Address = E0/E1 |
| NEC765 floppy disc controller | | NEC765 floppy disc controller |
| ----------------------------------------------------------
| | |
| Consult NEC765 datasheet. | | Consult NEC765 datasheet. |
|
| |
|
| Line 150: |
Line 148: |
|
| |
|
|
| |
|
| ---
| | [[NC100 IO Specification]] |
| Kev Thacker
| |
| | |
| | |
| | |
| | |
| Original NCIOSPEC.TXT follows:
| |
| | |
| The following notes describe the low level operation of the Amstrad Notepad
| |
| computers. They are intended for third party developers who want to program
| |
| the Notepad in machine code.
| |
| | |
| As always, I will try to help out if anyone has questions about this but I
| |
| cannot give an absolute guarantee to be able to provide support on the low
| |
| level operation of the machine.
| |
| | |
| It is our intention that these firmware routines and system variables should
| |
| be maintained in future issues of the software but we cannot give an absolute
| |
| guarantee about this.
| |
| | |
| Cliff Lawson CIS: 75300,1517
| |
| Notepad project manager email: cliffl@amstrad.com
| |
| Amstrad Plc amstrad@cix.compulink.co.uk
| |
| 169 Kings Road Phone: (+44) 277 208341
| |
| Brentwood Fax: (+44) 277 208065
| |
| Essex
| |
| CM14 4EF
| |
| ENGLAND
| |
| | |
| | |
| I/O 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/W
| |
| C0-C1 UART (uPD71051) R/W
| |
| B0-B9 Key data in R
| |
| A0 Card Status etc. R
| |
| 90 IRQ request status R/W
| |
| 80-8F Not Used
| |
| 70 Power on/off control W
| |
| 60 IRQ Mask W
| |
| 50-53 Speaker frequency W
| |
| 40 Parallel port data W
| |
| 30 Baud rate etc. W
| |
| 20 Card wiat control W
| |
| 10-13 Memory management R/W
| |
| 00 Display memory start W
| |
| | |
| | |
| In Detail
| |
| =========
| |
| | |
| Address = 00 Write only
| |
| start 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 4096
| |
| bytes where the first byte defines the state of the pixels in the top left
| |
| hand corner of the screen. A 1 bit set means the pixel is set to black. The
| |
| first byte controls the first 8 dots with bit 7 controlling the bit on the
| |
| left. The next 59 bytes complete the first raster line of 480 dots. The bytes
| |
| which define the second raster line start at byte 64 to make the hardware
| |
| simpler 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 on
| |
| straight down the screen. That is (all numbers decimal):
| |
| | |
| byte00 byte01 byte02 byte60 byte61 byte63
| |
| Bit Number 76543210 76543210 76543210 .. 76543210 76543210.. 76543210
| |
| | |
| Pixel Number 01234567 89012345 67890123 .. 23456789 wasted .. wasted
| |
| (read bottom 00000000 00111111 11112222 77777777
| |
| to top decimal) 00000000 00000000 00000000 44444444
| |
| | |
| ....and so on for subsequent lines. (Second line = bytes 64..127 etc.)
| |
| | |
| | |
| Address = 10..13 Read/Write
| |
| Memory 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 the
| |
| processor sees it at 4000-7FFF you would output the value 42 to I/O address
| |
| 11. 42 has bits 7,6 = 01b and bits 5-0 are 00010b which is the third 16K of
| |
| internal RAM.
| |
| | |
| | |
| Address = 20 Write only
| |
| Memory 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 is
| |
| 200nS or slower.
| |
| | |
| | |
| Address = 30 Write only
| |
| Baud 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 only
| |
| Parallel interface data
| |
| ----------------------------------------------------------
| |
| | |
| The byte written here is latched into the parallel port output register. To
| |
| print it you must then take the Strobe signal (I/O address 30 bit 6) low and
| |
| then high again. If the printer sends ACK this may generate an IRQ if the mask
| |
| bit is set in I/O address 60 - IRQ mask.
| |
| | |
| Address = 50..53 Write only
| |
| Sound 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) then
| |
| the 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 only
| |
| Interrupt 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 to
| |
| produce IRQs. 0 = interrupt source is masked.
| |
| | |
| Address = 70 Write only
| |
| Power 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/Write
| |
| IRQ 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 of
| |
| the 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 only
| |
| Memory 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 only
| |
| Keyboard 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 an
| |
| interrupt. The program should then read these 10 I/O locations to
| |
| determine which key(s) is pushed. When I/O address B9 is read the
| |
| key scan interrupt is cleared automatically and the next scan cycle
| |
| will start from B0.
| |
| | |
| Address = C0 Read/Write
| |
| UART control/data
| |
| ------------------------------------------------------------
| |
| | |
| C0 UART data register
| |
| C1 UART status/control register
| |
| | |
| The UART is the NEC uPD71051. Programmers are advised to study the data
| |
| sheet for that chip for more information. The Serial interface requires
| |
| that the uPD4711 line driver chip be truned on by writing a 0 to bit 4 of
| |
| I/O address 30. While turned on power consumption increases so this should
| |
| only be done when necessary.
| |
| | |
| Address = D0 Read/Write
| |
| Real 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 POKE
| |
| them 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 of
| |
| needing 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 drive
| |
| for your PC and write a binary image direct to the card using that. If
| |
| this isn't possible then small programs (up to 16K) can be developed by
| |
| transferring the binary card image into the Notepad using Xmodem from
| |
| the PC. The use the "Make program card" feature in the File, transfer
| |
| menu 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 to
| |
| the Z80 memory map at C000..FFFF. A Check is made that location C200
| |
| holds the ASCII text "NC100PRG" and also that locations C210..C212
| |
| contains a long jump to C220. All being well, the Z80 starts executing
| |
| code at C210 so that, once you have control, you can take over
| |
| completely if you wish (driving all hardware functions directly). Most
| |
| people will probably want to cooperate with the in built firmware as it
| |
| provides most of the routines that one would require anyway.
| |
| | |
| | |
| The ASCII text "NC100PRG" must appear at C200h
| |
| program origin is C210h
| |
| program MUST start with jp C220h
| |
| the 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 Ltd
| |
| on (+44) 604 589200 as they can produce a device that looks like RAM to
| |
| a PC but ends in a PCMCIA header plug that connects directly to the
| |
| Notepad'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 the
| |
| AVMACZ80 assembler on a PC, which, when assmembled produces a binary
| |
| file that can be programmed onto a PCMCIA card and executed. The
| |
| program just reads keys and prints them back until "Q" is pressed.
| |
| | |
| Notice that exit from the program is just by a RET back to the
| |
| operating 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 direct
| |
| ORG to locate code at C000 but watch out for the resultant .HEX file
| |
| being 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 in
| |
| the following and then call the relevant address. Although the running of the
| |
| routine may involve a different ROM bank being switched in, this mechanism
| |
| is 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 B818h
| |
| col1text equ B81Bh
| |
| diskservice equ BA5Eh
| |
| editbuf equ B800h
| |
| fclose equ B890h
| |
| fdatestamp equ B8C9h
| |
| ferase equ B893h
| |
| fgetattr equ B8CFh
| |
| finblock equ B896h
| |
| finchar equ B899h
| |
| findfirst equ B89Ch
| |
| findnext equ B89Fh
| |
| fnoisy equ B917h
| |
| fopenin equ B8A2h
| |
| fopenout equ B8A5h
| |
| fopenup equ B8A8h
| |
| foutblock equ B8ABh
| |
| foutchar equ B8AEh
| |
| fquiet equ B91Ah
| |
| frename equ B8B1h
| |
| fseek equ B8B4h
| |
| fsetattr equ B8CCh
| |
| fsize equ B8B7h
| |
| fsizehandle equ B8BAh
| |
| ftell equ B8BDh
| |
| ftesteof equ B8C0h
| |
| heapaddress equ B87Eh
| |
| heapalloc equ B881h
| |
| heapfree equ B884h
| |
| heaplock equ B887h
| |
| heapmaxfree equ B88Ah
| |
| heaprealloc equ B88Dh
| |
| kmcharreturn equ B803h
| |
| kmgetyellow equ B8D2h
| |
| kmreadkbd equ B806h
| |
| kmreadchar equ B9B3h
| |
| kmsetexpand equ B809h
| |
| kmsettickcount equ B80Ch
| |
| kmsetyellow equ B8D5h
| |
| kmwaitkbd equ B80Fh
| |
| lapcat_receive equ B8D8h
| |
| lapcat_send equ B8DBh
| |
| mcprintchar equ B851h
| |
| mcreadyprinter equ B854h
| |
| mcsetprinter equ B857h
| |
| padgetticker equ B872h
| |
| padgettime equ B875h
| |
| padgetversion equ B8DEh
| |
| padinitprinter equ BA4Fh
| |
| padinitserial equ B85Ah
| |
| padinserial equ B85Dh
| |
| padoutparallel equ B860h
| |
| padoutserial equ B863h
| |
| padreadyparallel equ B866h
| |
| padreadyserial equ B869h
| |
| padresetserial equ B86Ch
| |
| padserialwaiting equ B86Fh
| |
| padsetalarm equ B878h
| |
| padsettime equ B87Bh
| |
| pagemodeon equ BA49h
| |
| pagemodeoff equ BA4Ch
| |
| readbuf equ B812h
| |
| selectfile equ B8C3h
| |
| setdta equ B8C6h
| |
| testescape equ B815h
| |
| textout equ B81Eh
| |
| textoutcount equ B821h
| |
| txtboldoff equ B83Fh
| |
| txtboldon equ B842h
| |
| txtclearwindow equ B824h
| |
| txtcuroff equ B827h
| |
| txtcuron equ B82Ah
| |
| txtgetcursor equ B82Dh
| |
| txtgetwindow equ B830h
| |
| txtinverseoff equ B845h
| |
| txtinverseon equ B848h
| |
| txtoutput equ B833h
| |
| txtsetcursor equ B836h
| |
| txtsetwindow equ B839h
| |
| txtunderlineoff equ B84Bh
| |
| txtunderlineon equ B84Eh
| |
| txtwrchar 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 = B83F
| |
| txtboldon = B842
| |
| txtinverseoff = B845
| |
| txtinverseon = B848
| |
| txtunderlineoff = B84B
| |
| txtunderlineon = 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. It
| |
| is hoped that they will always use these locations in subsequent versions
| |
| of the software - but this is not guaranteed.
| |
| | |
| B000 copyofmmu0 ds 1 ; copy of MMU0 since it's a write-only port
| |
| B001 copyofmmu1 ds 1 ; copy of MMU1 since it's a write-only port
| |
| B002 copyofmmu2 ds 1 ; copy of MMU2 since it's a write-only port
| |
| B003 copyofmmu3 ds 1 ; copy of MMU3 since it's a write-only port
| |
|
| |
| B004 gotcontext ds 1
| |
| B005 __savepearlmmu ds 1 ; extra vars needed in case we mustn't save context
| |
| B006 __saveaf ds 2
| |
| B008 __savehl ds 2
| |
| B00A saveaf ds 2 ; to save context, we need to save all the registers ...
| |
| B00C savebc ds 2
| |
| B00E savede ds 2
| |
| B010 savehl ds 2
| |
| B012 saveix ds 2
| |
| B014 saveiy ds 2
| |
| B016 savepc ds 2
| |
| B018 savesp ds 2
| |
| B01A saveafdash ds 2
| |
| B01C savebcdash ds 2
| |
| B01E savededash ds 2
| |
| B020 savehldash ds 2
| |
| B022 savemmu0 ds 1 ; ... and the memory state
| |
| B023 savemmu1 ds 1
| |
| B024 savemmu2 ds 1
| |
| B025 savemmu3 ds 1
| |
| B026 savecritpc ds 2
| |
| B028 savecritsp ds 2
| |
| B02A savingcontext ds 1
| |
| B02B nmimagic ds 4
| |
| B02F nmichksums ds 8 ; checksum bytes of first 8 roms
| |
| B037 criticalpc ds 2 ; save pc,sp for recovery from NMI during IRQ
| |
| B039 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 context
| |
| B08B initstack
| |
| B08B diagnostics? ds 1 ; flag used in start-up, nonzero to do diagnostics
| |
| B08C saveprinstat ds 1
| |
| B08D kbdstate1 ds 10 ; 1 bit per key, 1=down 0=up corresponds to matrix
| |
| B097 kbdstate2 ds 10
| |
| | |
| PADKEYBUFLEN equ 32 ; this MUST be 2^n for positive integer n
| |
| B0A1 padkeybuf ds PADKEYBUFLEN*2
| |
| | |
| B0E1 padnextin ds 1 ; offset into padkeybuf
| |
| B0E2 padnextout ds 1
| |
| B0E3 padbufempty ds 1 ; nonzero if empty
| |
| B0E4 lastkbdstate ds 2
| |
| B0E6 thiskbdstate ds 2
| |
| B0E8 caps.state ds 1 ; 0=off FF=on
| |
| B0E9 savecaps ds 1
| |
| B0EA justswitchedon? ds 1
| |
|
| |
| ; variables above here are preserved after timeout
| |
|
| |
|
| |
| PADSERBUFLEN equ 32 ; this MUST be 2^n for positive integer n
| |
| B0EB padserbuf ds PADSERBUFLEN
| |
| B10B padsernextin ds 1
| |
| B10C padsernextout ds 1
| |
| B10D padserbufempty ds 1
| |
| B10E padserin_xoff ds 1 ; non-zero when XOFF has stopped inward transmission
| |
| B10F padserout_xoff ds 1 ; non-zero when XOFF has stopped outward transmission
| |
| B110 disablexonxoff ds 1 ; nonzero to disable software handshake
| |
|
| |
| B111 ackirq ds 1 ; set non-zero when ACK interrupt occurs
| |
|
| |
| B112 rptdelay ds 1 ; centisecs
| |
| B113 rptrate ds 1 ; centisecs
| |
| B114 rpttimer ds 1 ; count down timer for key repeat
| |
| B115 keytorepeat ds 1 ; key number
| |
| B116 rptkeystates ds 1 ; shift states
| |
|
| |
| B117 rtcbuf ds 13
| |
| B124 d.alarmday ds 6 ; alarm day,hour,min ready for rtc chip
| |
| B12A alarmhappened ds 1 ; non zero when alarm has gone off, message pending
| |
| B12B alarmhappenedgotmsg ds 1 ; non zero when alarm has gone off, got message & pending
| |
| B12C soundcounter ds 1 ; non-zero if we're playing a tune
| |
| B12D soundptr ds 2 ; pointer to array of frequency,duration
| |
| B12F soundrepcount ds 1
| |
| B130 soundrepptr ds 2
| |
| B132 poweroffminutes ds 1 ; configured time to power off
| |
| B133 minutesleft ds 1
| |
| B134 minutecounter ds 2
| |
| B136 eventhappened ds 1
| |
| B137 preservecontext ds 1 ; 0=return to main screen at power on
| |
| B138 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 serial
| |
| B13B currentmenu ds 2 ; pointer to current menu
| |
| B13D 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 time
| |
| B13F 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 boundary
| |
| B148 d.workspace ds 8 ; for massaged copy of symbol data (eg inverse/underline)
| |
|
| |
| B150 d.datebuf ds 9+MAXMONTHLEN ; 27 January 1992
| |
| B162 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 file
| |
| B1BB g.h.outfile ds 2 ; file handle for charout if bit 2 set
| |
| B1BD 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-8
| |
| B202 d.colrow ds 2-2 ; keep next 2 together
| |
| B202 d.row ds 1 ; 0-based within window
| |
| B203 d.col ds 1 ;
| |
|
| |
| B204 d.winlefttop ds 2-2 ; keep next 2 together
| |
| B204 d.wintop ds 1
| |
| B205 d.winleft ds 1
| |
| | |
| B206 d.winsize ds 2-2 ; keep next 2 together
| |
| B206 d.winheight ds 1 ; height -1
| |
| B207 d.winwidth ds 1 ; width -1
| |
|
| |
| B208 d.winset? ds 1 ; NZ if window
| |
| B209 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 together
| |
| B20A d.rowcount ds 1
| |
| B20B d.colcount ds 1 ; how many more cols to print on this line
| |
| B20C d.stream ds 1 ; current stream number
| |
| B20D 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/date
| |
| B251 d.kmcharret ds 2 ; Returned character
| |
| B253 d.kstate ds 2 ; Key locks state
| |
| B255 d.caslocks ds 1 ; Shift states set by sticky key press
| |
| B256 d.sticky ds 1 ; non-zero in sticky key mode
| |
| B257 d.yellow ds 1 ; low byte of yellow/other key token
| |
| ; stored by p.xlattoken which then returns ESC
| |
| B258 d.calcmode ds 1 ; nonzero if keyboard in calculator mode
| |
|
| |
| B259 d.kmexplen ds 1 ; expansion string length
| |
| B25A d.kmexpptr ds 2 ; expansion string pointer
| |
| B25C d.expbuffer ds 2 ; address of expansion key buffer
| |
| B25E d.expbufptr ds 2 ; pointer to free byte
| |
| B260 d.expbufend ds 2 ; last byte in buffer
| |
|
| |
| B2A1 macro_buf ds 256
| |
|
| |
| ; file selector variables
| |
| B3A7 fs_clicat ds 1 ; non-zero if CAT command, not fsel
| |
| B3A8 fs_showsizes ds 1 ; non-zero if showing file sizes (pad default=off)
| |
| B3A9 fs_showsys ds 1 ; non-zero if showing system files
| |
| B3AA fs_curfile ds 1 ; current file number offset from top left
| |
| B3AB fs_topleftfile ds 1 ; file number displayed top left
| |
| B3AC fs_numcols ds 1
| |
| B3AD fs_colwidth ds 1
| |
| B3AE fs_numshown ds 1
| |
| B3AF fs_maxfiles ds 1 ; max files that can be shown
| |
| FS_NUMROWS .equ 7 ; display rows
| |
| FS_NUMCOLS .equ 5
| |
| FS_COLWIDTH .equ 16
| |
| B3B0 fs_handle ds 2
| |
| FS_NUMSHOWN .equ FS_NUMCOLS*FS_NUMROWS
| |
| ; number of files shown
| |
| B3B2 fs_numfilerows ds 1 ; rows of files in CAT command
| |
| B3B3 fs_startlist ds 2 ; start of file list
| |
| ; zero if doing unsorted list
| |
| B3B5 fs_startdir ds 2 ; start of directory entries
| |
| B3B7 fs_endlist ds 2
| |
| B3B9 fs_numfiles ds 1 ; number of files in directory
| |
| B3BA fs_lastshown ds 1 ; last filenumber currently shown
| |
| ; fs_topleft + FS_NUMSHOWN
| |
|
| |
| B3BB tickcount ds 4 ; 32 bit counter needed for basic
| |
| B3BF ticksleftuntilevent ds 2
| |
| B3C1 tickreloadvalue ds 2
| |
| B3C3 tickeventpending ds 1
| |
| B3C4 countdowntimer ds 2
| |
|
| |
| B3C6 savestream ds 1
| |
|
| |
| B3C7 password ds 5 ; encrypted
| |
| B3CC pwbuf ds 5 ; clear
| |
| B3D1 realpwbuf ds 5 ; the real password saved for encrypting
| |
| B3D6 haspassword ds 1 ; non-zero if has password
| |
| ;passwdmsg ds 2
| |
| B3D7 passwdlen ds 1
| |
| B3D8 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 1
| |
| B3DC recording? ds 1
| |
| B3DD macro_token ds 2
| |
|
| |
| B3DF printfailed ds 1 ; flag set by mccheckprinter
| |
| ; stops "finished printing" message
| |
| B3E0 wasmemoryerr ds 1
| |
| B3E1 inprotext ds 1 ; used in file selector, 0=was Fn-L, nonzero=Fn-2
| |
| | |
| **** End ****
| |