| //; |
| //; sysdef.asm: This file contains definitions to simplify assembler programming |
| //; and for accessing the various hardware registers via MMIO |
| //; |
| // |
| //*************************************************************************************** |
| //* Assembler macros which make life much easier: |
| //*************************************************************************************** |
| // |
| |
| |
| // |
| // Some register short names: |
| // |
| |
| // |
| //*************************************************************************************** |
| //* IO-page addresses: Default: 8 registers per block |
| //*************************************************************************************** |
| // |
| #define IO_AREA_START 0xFF00 |
| // |
| //--------------------------------------------------------------------------------------- |
| // Block FF00: FUNDAMENTAL IO |
| //--------------------------------------------------------------------------------------- |
| // |
| // Switch-register: |
| // |
| #define IO_SWITCH_REG 0xFF00 // 16 binary keys |
| // |
| // Registers for TIL-display: |
| // |
| #define IO_TIL_DISPLAY 0xFF01 // Address of TIL-display |
| #define IO_TIL_MASK 0xFF02 // Mask register of TIL display |
| // |
| // USB-keyboard-registers: |
| // |
| #define IO_KBD_STATE 0xFF04 // Status register of USB keyboard |
| // Bit 0 (read only): New ASCII character avaiable for reading |
| // (bits 7 downto 0 of Read register) |
| // Bit 1 (read only): New special key available for reading |
| // (bits 15 downto 8 of Read register) |
| // Bits 2..4 (read/write): Locales: 000 = US English keyboard layout, |
| // 001 = German layout, others: reserved for more locales |
| // Bits 5..7 (read only): Modifiers: 5 = shift, 6 = alt, 7 = ctrl |
| // Only valid, when bits 0 and/or 1 are '1' |
| // |
| #define IO_KBD_DATA 0xFF05 // Data register of USB keyboard |
| // Contains the ASCII character in bits 7 downto 0 or the special key code |
| // in 15 downto 8. The "or" is meant exclusive, i.e. it cannot happen that |
| // one transmission contains an ASCII character PLUS a special character. |
| // |
| //--------------------------------------------------------------------------------------- |
| // Block FF08: SYSTEM COUNTERS |
| //--------------------------------------------------------------------------------------- |
| // |
| // CYCLE-COUNT-registers |
| // |
| #define IO_CYC_LO 0xFF08 // low word of 48-bit counter |
| #define IO_CYC_MID 0xFF09 // middle word of 48-bit counter |
| #define IO_CYC_HI 0xFF0A // high word of 48-bit counter |
| #define IO_CYC_STATE 0xFF0B // status register |
| // Bit 0 (write only): Reset counter to zero and start counting, i.e. |
| // bit 1 is automatically set to 1 when resetting |
| // Bit 1 (read/write): Start/stop counter |
| // |
| // INSTRUCTION-COUNT-registers |
| // |
| #define IO_INS_LO 0xFF0C // low word of 48-bit counter |
| #define IO_INS_MID 0xFF0D // middle word of 48-bit counter |
| #define IO_INS_HI 0xFF0E // high word of 48-bit counter |
| #define IO_INS_STATE 0xFF0F // status register |
| // Bit 0 (write only): Reset counter to zero and start counting, i.e. |
| // bit 1 is automatically set to 1 when resetting |
| // Bit 1 (read/write): Start/stop counter |
| // |
| //--------------------------------------------------------------------------------------- |
| // Block FF10: UART |
| //--------------------------------------------------------------------------------------- |
| // |
| // QNICE-FPGA supports: IO_UART_SRA, IO_UART_RHRA and IO_UART_THRA |
| // The other registers are mentioned for completeness to map real hardware (16550) |
| // |
| #define IO_UART_BASE_ADDRESS 0xFF10 |
| #define IO_UART_MR1A 0xFF10 // n/a |
| #define IO_UART_MR1B 0xFF10 // n/a |
| #define IO_UART_SRA 0xFF11 // Status register (relative to base address) |
| #define IO_UART_RHRA 0xFF12 // Receiving register (relative to base address) |
| #define IO_UART_THRA 0xFF13 // Transmitting register (relative to base address) |
| // |
| //--------------------------------------------------------------------------------------- |
| // Block FF18: EAE |
| //--------------------------------------------------------------------------------------- |
| // |
| // EAE (Extended Arithmetic Element) registers: |
| // |
| #define IO_EAE_OPERAND_0 0xFF18 |
| #define IO_EAE_OPERAND_1 0xFF19 |
| #define IO_EAE_RESULT_LO 0xFF1A |
| #define IO_EAE_RESULT_HI 0xFF1B |
| #define IO_EAE_CSR 0xFF1C // Command and Status Register |
| // |
| // EAE-Opcodes (CSR): 0x0000 MULU 32-bit result in LO HI |
| // 0x0001 MULS 32-bit result in LO HI |
| // 0x0002 DIVU result in LO, modulo in HI |
| // 0x0003 DIVS result in LO, modulo in HI |
| // Bit 15 of CSR is the busy bit. If it is set, the EAE is still busy crunching numbers. |
| // |
| //--------------------------------------------------------------------------------------- |
| // Block FF20: SD CARD |
| //--------------------------------------------------------------------------------------- |
| // |
| // SD CARD INTERFACE registers |
| // |
| #define IO_SD_BASE_ADDRESS 0xFF20 |
| #define IO_SD_ADDR_LO 0xFF20 // low word of 32bit linear SD card block address |
| #define IO_SD_ADDR_HI 0xFF21 // high word of 32bit linear SD card block address |
| #define IO_SD_DATA_POS 0xFF22 // "Cursor" to navigate the 512-byte data buffer |
| #define IO_SD_DATA 0xFF23 // read/write 1 byte from/to the 512-byte data buffer |
| #define IO_SD_ERROR 0xFF24 // error code of last operation (read only) |
| #define IO_SD_CSR 0xFF25 // Command and Status Register (write to execute command) |
| // |
| // SD-Opcodes (CSR): 0x0000 Reset SD card |
| // 0x0001 Read 512 bytes from the linear block address |
| // 0x0002 Write 512 bytes to the linear block address |
| // Bits 0 .. 2 are write-only (reading always returns 0) |
| // Bits 13 .. 12 return the card type: 00 = no card / unknown card |
| // 01 = SD V1 |
| // 10 = SD V2 |
| // 11 = SDHC |
| // Bit 14 of the CSR is the error bit: 1, if the last operation failed. In such |
| // a case, the error code is in IO_SD_ERROR and |
| // you need to reset the controller to go on |
| // Bit 15 of the CSR is the busy bit: 1, if current operation is still running |
| // |
| //--------------------------------------------------------------------------------------- |
| // Block FF28: TIMER 0 and 1 |
| //--------------------------------------------------------------------------------------- |
| // |
| // Interrupt timer: There are two timers capable of generating interrupts. |
| // Each timer is controlled by three 16 bit registers: |
| // |
| // IO_TIMER_x_PRE: The 100 kHz timer clock is divided by the value stored in |
| // this device register. 100 (which corresponds to 0x0064 in |
| // the prescaler register) yields a 1 millisecond pulse which |
| // in turn is fed to the actual counter. |
| // IO_TIMER_x_CNT: When the number of output pulses from the prescaler circuit |
| // equals the number stored in this register, an interrupt will |
| // be generated (if the interrupt address is 0x0000, the |
| // interrupt will be suppressed). |
| // IO_TIMER_x_INT: This register contains the address of the desired interrupt |
| // service routine. |
| // |
| #define IO_TIMER_BASE_ADDRESS 0xFF28 |
| #define IO_TIMER_0_PRE 0xFF28 |
| #define IO_TIMER_0_CNT 0xFF29 |
| #define IO_TIMER_0_INT 0xFF2A |
| #define IO_TIMER_1_PRE 0xFF2B |
| #define IO_TIMER_1_CNT 0xFF2C |
| #define IO_TIMER_1_INT 0xFF2D |
| // |
| //--------------------------------------------------------------------------------------- |
| // Block FF30: VGA (double block, 16 registers) |
| //--------------------------------------------------------------------------------------- |
| // |
| #define VGA_STATE 0xFF30 // VGA status register |
| // Bits 11-10: Hardware scrolling / offset enable: Bit #10 enables the use |
| // of the offset register #4 (display offset) and bit #11 |
| // enables the use of register #5 (read/write offset). |
| // Bit 9: Busy: VGA is currently busy, e.g. clearing the screen, |
| // printing, etc. While busy, commands will be ignored, but |
| // they can still be written into the registers, though |
| // Bit 8: Set bit to clear screen. Read bit to find out, if clear |
| // screen is still active |
| // Bit 7: VGA enable (1 = on; 0: no VGA signal is generated) |
| // Bit 6: Hardware cursor enable |
| // Bit 5: Hardware cursor blink enable |
| // Bit 4: Hardware cursor mode: 1 - small |
| // 0 - large |
| // Bits 2-0: Output color for the whole screen, bits (2, 1, 0) = RGB |
| #define VGA_CR_X 0xFF31 // VGA cursor X position |
| #define VGA_CR_Y 0xFF32 // VGA cursor Y position |
| #define VGA_CHAR 0xFF33 // write: VGA character to be displayed |
| // read: character "under" the cursor |
| #define VGA_OFFS_DISPLAY 0xFF34 // Offset in bytes that is used when displaying |
| // the video RAM. Scrolling forward one line |
| // means adding 0x50 to this register. |
| // Only works, if bit #10 in VGA_STATE is set. |
| #define VGA_OFFS_RW 0xFF35 // Offset in bytes that is used, when you read |
| // or write to the video RAM using VGA_CHAR. |
| // Works independently from VGA_OFFS_DISPLAY. |
| // Active, when bit #11 in VGA_STATE is set. |
| #define VGA_HDMI_H_MIN 0xFF36 // HDMI Data Enable: X: minimum valid column |
| #define VGA_HDMI_H_MAX 0xFF37 // HDMI Data Enable: X: maximum valid column |
| #define VGA_HDMI_V_MAX 0xFF38 // HDMI Data Enable: Y: maximum row (line) |
| // |
| //--------------------------------------------------------------------------------------- |
| // Block FFF0: MEGA65 (double block, 16 registers) |
| //--------------------------------------------------------------------------------------- |
| // |
| // HyperRAM |
| // |
| #define IO_M65HRAM_LO 0xFFF0 // Low word of address (15 downto 0) |
| #define IO_M65HRAM_HI 0xFFF1 // High word of address (26 downto 16) |
| #define IO_M65HRAM_DATA8 0xFFF2 // HyperRAM native 8-bit data in/out |
| #define IO_M65HRAM_DATA16 0xFFF3 // HyperRAM 16-bit data in/out |
| |
| // |
| //*************************************************************************************** |
| //* Constant definitions |
| //*************************************************************************************** |
| // |
| |
| // ========== VGA ========== |
| |
| #define VGA_MAX_X 79 // Max. X-coordinate in decimal! |
| #define VGA_MAX_Y 39 // Max. Y-coordinate in decimal! |
| #define VGA_MAX_CHARS 3200 // 80 * 40 chars |
| #define VGA_CHARS_PER_LINE 80 |
| |
| #define VGA_EN_HW_CURSOR 0x0040 // Show hardware cursor |
| #define VGA_EN_HW_SCRL 0x0C00 // Hardware scrolling enable |
| #define VGA_CLR_SCRN 0x0100 // Clear screen |
| #define VGA_BUSY 0x0200 // VGA is currently performing a task |
| |
| #define VGA_COLOR_RED 0x0004 |
| #define VGA_COLOR_GREEN 0x0002 |
| #define VGA_COLOR_BLUE 0x0001 |
| #define VGA_COLOR_WHITE 0x0007 |
| |
| // ========== CYCLE COUNTER ========== |
| |
| #define CYC_RESET 0x0001 // Reset cycle counter |
| #define CYC_RUN 0x0002 // Start/stop counter |
| |
| // ========== CYCLE COUNTER ========== |
| |
| #define INS_RESET 0x0001 // Reset instruction counter |
| #define INS_RUN 0x0002 // Start/stop counter |
| |
| // ========== EAE ========== |
| |
| #define EAE_MULU 0x0000 // Unsigned 16 bit multiplication |
| #define EAE_MULS 0x0001 // Signed 16 bit multiplication |
| #define EAE_DIVU 0x0002 // Unsigned 16 bit division with remainder |
| #define EAE_DIVS 0x0003 // Signed 16 bit division with remainder |
| #define EAE_BUSY 0x8000 // Busy flag (1 = operation still running) |
| |
| // ========== SD CARD ========== |
| |
| #define SD_CMD_RESET 0x0000 // Reset SD card |
| #define SD_CMD_READ 0x0001 // Read 512 bytes from SD to internal buffer |
| #define SD_CMD_WRITE 0x0002 // Write 512 bytes from int. buf. to SD |
| #define SD_BIT_ERROR 0x4000 // Error flag: 1, if last operation failed |
| #define SD_BIT_BUSY 0x8000 // Busy flag: 1, if current op. is still running |
| #define SD_TIMEOUT_MID 0x0479 // equals ~75.000.000 cycles, i.e. 1.5sec @ 50 MHz |
| |
| #define SD_ERR_MASK 0x00FF // AND mask for errors: HI byte = state machine info, so mask it for error checks |
| #define SD_ERR_R1_ERROR 0x0001 // SD Card R1 error (R1 bit 6-0) |
| #define SD_ERR_CRC_OR_TIMEOUT 0x0002 // Read CRC error or Write Timeout error |
| #define SD_ERR_RESPONSE_TOKEN 0x0003 // Data Response Token error (Token bit 3) |
| #define SD_ERR_ERROR_TOKEN 0x0004 // Data Error Token error (Token bit 3-0) |
| #define SD_ERR_WRITE_PROTECT 0x0005 // SD Card Write Protect switch |
| #define SD_ERR_CARD_UNUSABLE 0x0006 // Unusable SD card |
| #define SD_ERR_NO_CARD 0x0007 // No SD card (no response from CMD0) |
| #define SD_ERR_READ_TIMEOUT 0x0008 // Timeout while trying to receive the read start token "FE" |
| #define SD_ERR_TIMEOUT 0xEEFF // General timeout |
| |
| #define SD_CT_SD_V1 0x0001 // Card type: SD Version 1 |
| #define SD_CT_SD_V2 0x0002 // Card type: SD Version 2 |
| #define SD_CT_SDHC 0x0003 // Card type: SDHC (or SDXC) |
| |
| // ========== FAT32 ============= |
| |
| // FAT32 ERROR CODES |
| |
| #define FAT32_ERR_MBR 0xEE10 // no or illegal Master Boot Record (MBR) found |
| #define FAT32_ERR_PARTITION_NO 0xEE11 // the partition number needs to be in the range 1 .. 4 |
| #define FAT32_ERR_PARTTBL 0xEE12 // no or illegal partition table entry found (e.g. no FAT32 partition) |
| #define FAT32_ERR_NOTIMPL 0xEE13 // functionality is not implemented |
| #define FAT32_ERR_SIZE 0xEE14 // partition size or volume size too large (see doc/constraints.txt) |
| #define FAT32_ERR_NOFAT32 0xEE15 // illegal volume id (either not 512 bytes per sector, or not 2 FATs or wrong magic) |
| #define FAT32_ERR_ILLEGAL_SIC 0xEE16 // trying to read/write a sector within a cluster that is out of range |
| #define FAT32_ERR_ILLEGAL_CLUS 0xEE17 // trying to access an illegal cluster number |
| #define FAT32_ERR_CORRUPT_DH 0xEE18 // corrupt directory handle (e.g. because current to-be-read offs > sector size) |
| #define FAT32_ERR_DIRNOTFOUND 0xEE19 // directory not found (illegal path name passed to change directory command) |
| #define FAT32_ERR_FILENOTFOUND 0xEE20 // file not found |
| #define FAT23_ERR_SEEKTOOLARGE 0xEE21 // seek position > file size |
| |
| // FAT32 STATUS CODES |
| |
| #define FAT32_EOF 0xEEEE // end of file reached |
| |
| // LAYOUT OF THE MOUNT DATA STRUCTURE (DEVICE HANDLE) |
| |
| #define FAT32_DEV_RESET 0x0000 // pointer to device reset function |
| #define FAT32_DEV_BLOCK_READ 0x0001 // pointer to 512-byte block read function |
| #define FAT32_DEV_BLOCK_WRITE 0x0002 // pointer to 512-byte block write function |
| #define FAT32_DEV_BYTE_READ 0x0003 // pointer to 1-byte read function (within block buffer) |
| #define FAT32_DEV_BYTE_WRITE 0x0004 // pointer to 1-byte write function (within block buffer) |
| #define FAT32_DEV_PARTITION 0x0005 // number of partition to be mounted |
| #define FAT32_DEV_FS_LO 0x0006 // file system start address (LBA): low word |
| #define FAT32_DEV_FS_HI 0x0007 // file system start address (LBA): high word |
| #define FAT32_DEV_FAT_LO 0x0008 // fat start address (LBA): low word |
| #define FAT32_DEV_FAT_HI 0x0009 // fat start address (LBA): high word |
| #define FAT32_DEV_CLUSTER_LO 0x000A // cluster start address (LBA): low word |
| #define FAT32_DEV_CLUSTER_HI 0x000B // cluster start address (LBA): high word |
| #define FAT32_DEV_SECT_PER_CLUS 0x000C // sectors per cluster |
| #define FAT32_DEV_RD_1STCLUS_LO 0x000D // root directory first cluster: low word |
| #define FAT32_DEV_RD_1STCLUS_HI 0x000E // root directory first cluster: high word |
| #define FAT32_DEV_AD_1STCLUS_LO 0x000F // currently active directory first cluster: low word |
| #define FAT32_DEV_AD_1STCLUS_HI 0x0010 // currently active directory first cluster: high word |
| #define FAT32_DEV_BUFFERED_FDH 0x0011 // FDH which is responsible for the current 512 byte hardware buffer filling |
| |
| #define FAT32_DEV_STRUCT_SIZE 0x0012 // size (words) of the mount data structure (device handle) |
| |
| // LAYOUT OF THE FILE HANDLE AND DIRECTORY HANDLE (FDH) |
| |
| #define FAT32_FDH_DEVICE 0x0000 // pointer to the device handle |
| #define FAT32_FDH_CLUSTER_LO 0x0001 // current cluster (low word) |
| #define FAT32_FDH_CLUSTER_HI 0x0002 // current cluster (high word) |
| #define FAT32_FDH_SECTOR 0x0003 // current sector |
| #define FAT32_FDH_INDEX 0x0004 // current byte index within current sector |
| #define FAT32_FDH_SIZE_LO 0x0005 // only in case FDH is a file: low word of file size, otherwise undefined |
| #define FAT32_FDH_SIZE_HI 0x0006 // only in case FDH is a file: high word of file size, otherwise undefined |
| #define FAT32_FDH_READ_LO 0x0007 // only in case FDH is a file: low word of already read amount of bytes |
| #define FAT32_FDH_READ_HI 0x0008 // only in case FDH is a file: high word of already read amount of bytes |
| |
| #define FAT32_FDH_STRUCT_SIZE 0x0009 // size of the directory handle structure |
| |
| // FILE ATTRIBUTES |
| |
| #define FAT32_FA_READ_ONLY 0x0001 // read only file |
| #define FAT32_FA_HIDDEN 0x0002 // hidden file |
| #define FAT32_FA_SYSTEM 0x0004 // system file |
| #define FAT32_FA_VOLUME_ID 0x0008 // volume id (name of the volume) |
| #define FAT32_FA_DIR 0x0010 // directory |
| #define FAT32_FA_ARCHIVE 0x0020 // archive flag |
| |
| #define FAT32_FA_DEFAULT 0x0035 // browse for non hidden files and directories but not for the volume id |
| #define FAT32_FA_ALL 0x0037 // browse for all files, but not for the volume id |
| |
| // LAYOUT OF THE DIRECTORY ENTRY STRUCTURE |
| |
| #define FAT32_DE_NAME 0x0000 // volume, file or directory name, zero terminated (max 256 characters) |
| #define FAT32_DE_ATTRIB 0x0101 // file attributes (read-only, hidden, system, volume id, directory, archive) |
| #define FAT32_DE_SIZE_LO 0x0102 // file size: low word |
| #define FAT32_DE_SIZE_HI 0x0103 // file size: high word |
| #define FAT32_DE_YEAR 0x0104 // last file write: year (valid range 1980 .. 2107) |
| #define FAT32_DE_MONTH 0x0105 // last file write: month |
| #define FAT32_DE_DAY 0x0106 // last file write: day |
| #define FAT32_DE_HOUR 0x0107 // last file write: hour |
| #define FAT32_DE_MINUTE 0x0108 // last file write: minute |
| #define FAT32_DE_SECOND 0x0109 // last file write: second (in 2 second steps, valid range 0 .. 58) |
| #define FAT32_DE_CLUS_LO 0x010A // start cluster: low word |
| #define FAT32_DE_CLUS_HI 0x010B // start cluster: high word |
| |
| #define FAT32_DE_STRUCT_SIZE 0x010C // size (words) of the directory entry data structure of the |
| |
| // DISPLAY FLAGS FOR FILE ENTRY PRETTY PRINTER |
| |
| #define FAT32_PRINT_SHOW_DIR 0x0001 // show "<DIR>" indicator |
| #define FAT32_PRINT_SHOW_ATTRIB 0x0002 // show attributes as "HRSA" |
| #define FAT32_PRINT_SHOW_SIZE 0x0004 // show file size |
| #define FAT32_PRINT_SHOW_DATE 0x0008 // show file date as YYYY-MM-DD |
| #define FAT32_PRINT_SHOW_TIME 0x0010 // show file time as HH:MM |
| |
| #define FAT32_PRINT_DEFAULT 0x001D // print <DIR> indicator, size, date and time (no attributes) |
| #define FAT32_PRINT_ALL 0x001F // print all details |
| |
| // ========== KEYBOARD ========== |
| |
| // STATUS REGISTER |
| |
| #define KBD_NEW_ASCII 0x0001 // new ascii character available |
| #define KBD_NEW_SPECIAL 0x0002 // new special key available |
| #define KBD_NEW_ANY 0x0003 // any new key available |
| |
| #define KBD_ASCII 0x00FF // mask the special keys |
| #define KBD_SPECIAL 0xFF00 // mask the ascii keys |
| |
| #define KBD_LOCALE 0x001C // bit mask for checking locales |
| #define KBD_LOCALE_US 0x0000 // default: US keyboard layout |
| #define KBD_LOCALE_DE 0x0004 // DE: German keyboard layout |
| |
| #define KBD_MODIFIERS 0x00E0 // bit mask for checking modifiers |
| #define KBD_SHIFT 0x0020 // modifier "SHIFT" pressed |
| #define KBD_ALT 0x0040 // modifier "ALT" pressed |
| #define KBD_CTRL 0x0080 // modifier "CTRL" pressed |
| |
| // READ REGISTER: COMMON ASCII CODES |
| |
| #define KBD_SPACE 0x0020 |
| #define KBD_ENTER 0x000D |
| #define KBD_ESC 0x001B |
| #define KBD_TAB 0x0009 |
| #define KBD_BACKSPACE 0x0008 |
| |
| // READ REGISTER: SPECIAL KEYS |
| |
| #define KBD_F1 0x0100 |
| #define KBD_F2 0x0200 |
| #define KBD_F3 0x0300 |
| #define KBD_F4 0x0400 |
| #define KBD_F5 0x0500 |
| #define KBD_F6 0x0600 |
| #define KBD_F7 0x0700 |
| #define KBD_F8 0x0800 |
| #define KBD_F9 0x0900 |
| #define KBD_F10 0x0A00 |
| #define KBD_F11 0x0B00 |
| #define KBD_F12 0x0C00 |
| |
| #define KBD_CUR_UP 0x1000 |
| #define KBD_CUR_DOWN 0x1100 |
| #define KBD_CUR_LEFT 0x1200 |
| #define KBD_CUR_RIGHT 0x1300 |
| #define KBD_PG_UP 0x1400 |
| #define KBD_PG_DOWN 0x1500 |
| #define KBD_HOME 0x1600 |
| #define KBD_END 0x1700 |
| #define KBD_INS 0x1800 |
| #define KBD_DEL 0x1900 |
| |
| // READ REGISTER: CTRL + character is also mapped to an ASCII code |
| |
| #define KBD_CTRL_A 0x0001 |
| #define KBD_CTRL_B 0x0002 |
| #define KBD_CTRL_C 0x0003 |
| #define KBD_CTRL_D 0x0004 |
| #define KBD_CTRL_E 0x0005 |
| #define KBD_CTRL_F 0x0006 |
| #define KBD_CTRL_G 0x0007 |
| #define KBD_CTRL_H 0x0008 |
| #define KBD_CTRL_I 0x0009 |
| #define KBD_CTRL_J 0x000A |
| #define KBD_CTRL_K 0x000B |
| #define KBD_CTRL_L 0x000C |
| #define KBD_CTRL_M 0x000D |
| #define KBD_CTRL_N 0x000E |
| #define KBD_CTRL_O 0x000F |
| #define KBD_CTRL_P 0x0010 |
| #define KBD_CTRL_Q 0x0011 |
| #define KBD_CTRL_R 0x0012 |
| #define KBD_CTRL_S 0x0013 |
| #define KBD_CTRL_T 0x0014 |
| #define KBD_CTRL_U 0x0015 |
| #define KBD_CTRL_V 0x0016 |
| #define KBD_CTRL_W 0x0017 |
| #define KBD_CTRL_X 0x0018 |
| #define KBD_CTRL_Y 0x0019 |
| #define KBD_CTRL_Z 0x001A |
| |
| // |
| // Useful ASCII constants: |
| // |
| #define CHR_BELL 0x0007 // ASCII-BELL character |
| #define CHR_TAB 0x0009 // ASCII-TAB character |
| #define CHR_SPACE 0x0020 // ASCII-Space |
| #define CHR_CR 0x000d // Carriage return |
| #define CHR_LF 0x000a // Line feed |