text:
.global handle_interrupt_0
.align 32
handle_interrupt_0:
push rdi
mov rdi, 0
jmp handle_interrupt_

.global handle_interrupt_1
.align 32
handle_interrupt_1:
push rdi
mov rdi, 1
jmp handle_interrupt_

.global handle_interrupt_2
.align 32
handle_interrupt_2:
push rdi
mov rdi, 2
jmp handle_interrupt_

.global handle_interrupt_3
.align 32
handle_interrupt_3:
push rdi
mov rdi, 3
jmp handle_interrupt_

.global handle_interrupt_4
.align 32
handle_interrupt_4:
push rdi
mov rdi, 4
jmp handle_interrupt_

.global handle_interrupt_5
.align 32
handle_interrupt_5:
push rdi
mov rdi, 5
jmp handle_interrupt_

.global handle_interrupt_6
.align 32
handle_interrupt_6:
push rdi
mov rdi, 6
jmp handle_interrupt_

.global handle_interrupt_7
.align 32
handle_interrupt_7:
push rdi
mov rdi, 7
jmp handle_interrupt_

.global handle_interrupt_8
.align 32
handle_interrupt_8:
push rdi
mov rdi, 8
jmp handle_interrupt_

.global handle_interrupt_9
.align 32
handle_interrupt_9:
push rdi
mov rdi, 9
jmp handle_interrupt_

.global handle_interrupt_10
.align 32
handle_interrupt_10:
push rdi
mov rdi, 10
jmp handle_interrupt_

.global handle_interrupt_11
.align 32
handle_interrupt_11:
push rdi
mov rdi, 11
jmp handle_interrupt_

.global handle_interrupt_12
.align 32
handle_interrupt_12:
push rdi
mov rdi, 12
jmp handle_interrupt_

.global handle_interrupt_13
.align 32
handle_interrupt_13:
push rdi
mov rdi, 13
jmp handle_interrupt_

.global handle_interrupt_14
.align 32
handle_interrupt_14:
push rdi
mov rdi, 14
jmp handle_interrupt_

.global handle_interrupt_15
.align 32
handle_interrupt_15:
push rdi
mov rdi, 15
jmp handle_interrupt_

.global handle_interrupt_16
.align 32
handle_interrupt_16:
push rdi
mov rdi, 16
jmp handle_interrupt_

.global handle_interrupt_17
.align 32
handle_interrupt_17:
push rdi
mov rdi, 17
jmp handle_interrupt_

.global handle_interrupt_18
.align 32
handle_interrupt_18:
push rdi
mov rdi, 18
jmp handle_interrupt_

.global handle_interrupt_19
.align 32
handle_interrupt_19:
push rdi
mov rdi, 19
jmp handle_interrupt_

.global handle_interrupt_20
.align 32
handle_interrupt_20:
push rdi
mov rdi, 20
jmp handle_interrupt_

.global handle_interrupt_21
.align 32
handle_interrupt_21:
push rdi
mov rdi, 21
jmp handle_interrupt_

.global handle_interrupt_22
.align 32
handle_interrupt_22:
push rdi
mov rdi, 22
jmp handle_interrupt_

.global handle_interrupt_23
.align 32
handle_interrupt_23:
push rdi
mov rdi, 23
jmp handle_interrupt_

.global handle_interrupt_24
.align 32
handle_interrupt_24:
push rdi
mov rdi, 24
jmp handle_interrupt_

.global handle_interrupt_25
.align 32
handle_interrupt_25:
push rdi
mov rdi, 25
jmp handle_interrupt_

.global handle_interrupt_26
.align 32
handle_interrupt_26:
push rdi
mov rdi, 26
jmp handle_interrupt_

.global handle_interrupt_27
.align 32
handle_interrupt_27:
push rdi
mov rdi, 27
jmp handle_interrupt_

.global handle_interrupt_28
.align 32
handle_interrupt_28:
push rdi
mov rdi, 28
jmp handle_interrupt_

.global handle_interrupt_29
.align 32
handle_interrupt_29:
push rdi
mov rdi, 29
jmp handle_interrupt_

.global handle_interrupt_30
.align 32
handle_interrupt_30:
push rdi
mov rdi, 30
jmp handle_interrupt_

.global handle_interrupt_31
.align 32
handle_interrupt_31:
push rdi
mov rdi, 31
jmp handle_interrupt_

.global handle_interrupt_32
.align 32
handle_interrupt_32:
push rdi
mov rdi, 32
jmp handle_interrupt_

.global handle_interrupt_33
.align 32
handle_interrupt_33:
push rdi
mov rdi, 33
jmp handle_interrupt_

.global handle_interrupt_34
.align 32
handle_interrupt_34:
push rdi
mov rdi, 34
jmp handle_interrupt_

.global handle_interrupt_35
.align 32
handle_interrupt_35:
push rdi
mov rdi, 35
jmp handle_interrupt_

.global handle_interrupt_36
.align 32
handle_interrupt_36:
push rdi
mov rdi, 36
jmp handle_interrupt_

.global handle_interrupt_37
.align 32
handle_interrupt_37:
push rdi
mov rdi, 37
jmp handle_interrupt_

.global handle_interrupt_38
.align 32
handle_interrupt_38:
push rdi
mov rdi, 38
jmp handle_interrupt_

.global handle_interrupt_39
.align 32
handle_interrupt_39:
push rdi
mov rdi, 39
jmp handle_interrupt_

.global handle_interrupt_40
.align 32
handle_interrupt_40:
push rdi
mov rdi, 40
jmp handle_interrupt_

.global handle_interrupt_41
.align 32
handle_interrupt_41:
push rdi
mov rdi, 41
jmp handle_interrupt_

.global handle_interrupt_42
.align 32
handle_interrupt_42:
push rdi
mov rdi, 42
jmp handle_interrupt_

.global handle_interrupt_43
.align 32
handle_interrupt_43:
push rdi
mov rdi, 43
jmp handle_interrupt_

.global handle_interrupt_44
.align 32
handle_interrupt_44:
push rdi
mov rdi, 44
jmp handle_interrupt_

.global handle_interrupt_45
.align 32
handle_interrupt_45:
push rdi
mov rdi, 45
jmp handle_interrupt_

.global handle_interrupt_46
.align 32
handle_interrupt_46:
push rdi
mov rdi, 46
jmp handle_interrupt_

.global handle_interrupt_47
.align 32
handle_interrupt_47:
push rdi
mov rdi, 47
jmp handle_interrupt_

.global handle_interrupt_48
.align 32
handle_interrupt_48:
push rdi
mov rdi, 48
jmp handle_interrupt_

.global handle_interrupt_49
.align 32
handle_interrupt_49:
push rdi
mov rdi, 49
jmp handle_interrupt_

.global handle_interrupt_50
.align 32
handle_interrupt_50:
push rdi
mov rdi, 50
jmp handle_interrupt_

.global handle_interrupt_51
.align 32
handle_interrupt_51:
push rdi
mov rdi, 51
jmp handle_interrupt_

.global handle_interrupt_52
.align 32
handle_interrupt_52:
push rdi
mov rdi, 52
jmp handle_interrupt_

.global handle_interrupt_53
.align 32
handle_interrupt_53:
push rdi
mov rdi, 53
jmp handle_interrupt_

.global handle_interrupt_54
.align 32
handle_interrupt_54:
push rdi
mov rdi, 54
jmp handle_interrupt_

.global handle_interrupt_55
.align 32
handle_interrupt_55:
push rdi
mov rdi, 55
jmp handle_interrupt_

.global handle_interrupt_56
.align 32
handle_interrupt_56:
push rdi
mov rdi, 56
jmp handle_interrupt_

.global handle_interrupt_57
.align 32
handle_interrupt_57:
push rdi
mov rdi, 57
jmp handle_interrupt_

.global handle_interrupt_58
.align 32
handle_interrupt_58:
push rdi
mov rdi, 58
jmp handle_interrupt_

.global handle_interrupt_59
.align 32
handle_interrupt_59:
push rdi
mov rdi, 59
jmp handle_interrupt_

.global handle_interrupt_60
.align 32
handle_interrupt_60:
push rdi
mov rdi, 60
jmp handle_interrupt_

.global handle_interrupt_61
.align 32
handle_interrupt_61:
push rdi
mov rdi, 61
jmp handle_interrupt_

.global handle_interrupt_62
.align 32
handle_interrupt_62:
push rdi
mov rdi, 62
jmp handle_interrupt_

.global handle_interrupt_63
.align 32
handle_interrupt_63:
push rdi
mov rdi, 63
jmp handle_interrupt_

.global handle_interrupt_64
.align 32
handle_interrupt_64:
push rdi
mov rdi, 64
jmp handle_interrupt_

.global handle_interrupt_65
.align 32
handle_interrupt_65:
push rdi
mov rdi, 65
jmp handle_interrupt_

.global handle_interrupt_66
.align 32
handle_interrupt_66:
push rdi
mov rdi, 66
jmp handle_interrupt_

.global handle_interrupt_67
.align 32
handle_interrupt_67:
push rdi
mov rdi, 67
jmp handle_interrupt_

.global handle_interrupt_68
.align 32
handle_interrupt_68:
push rdi
mov rdi, 68
jmp handle_interrupt_

.global handle_interrupt_69
.align 32
handle_interrupt_69:
push rdi
mov rdi, 69
jmp handle_interrupt_

.global handle_interrupt_70
.align 32
handle_interrupt_70:
push rdi
mov rdi, 70
jmp handle_interrupt_

.global handle_interrupt_71
.align 32
handle_interrupt_71:
push rdi
mov rdi, 71
jmp handle_interrupt_

.global handle_interrupt_72
.align 32
handle_interrupt_72:
push rdi
mov rdi, 72
jmp handle_interrupt_

.global handle_interrupt_73
.align 32
handle_interrupt_73:
push rdi
mov rdi, 73
jmp handle_interrupt_

.global handle_interrupt_74
.align 32
handle_interrupt_74:
push rdi
mov rdi, 74
jmp handle_interrupt_

.global handle_interrupt_75
.align 32
handle_interrupt_75:
push rdi
mov rdi, 75
jmp handle_interrupt_

.global handle_interrupt_76
.align 32
handle_interrupt_76:
push rdi
mov rdi, 76
jmp handle_interrupt_

.global handle_interrupt_77
.align 32
handle_interrupt_77:
push rdi
mov rdi, 77
jmp handle_interrupt_

.global handle_interrupt_78
.align 32
handle_interrupt_78:
push rdi
mov rdi, 78
jmp handle_interrupt_

.global handle_interrupt_79
.align 32
handle_interrupt_79:
push rdi
mov rdi, 79
jmp handle_interrupt_

.global handle_interrupt_80
.align 32
handle_interrupt_80:
push rdi
mov rdi, 80
jmp handle_interrupt_

.global handle_interrupt_81
.align 32
handle_interrupt_81:
push rdi
mov rdi, 81
jmp handle_interrupt_

.global handle_interrupt_82
.align 32
handle_interrupt_82:
push rdi
mov rdi, 82
jmp handle_interrupt_

.global handle_interrupt_83
.align 32
handle_interrupt_83:
push rdi
mov rdi, 83
jmp handle_interrupt_

.global handle_interrupt_84
.align 32
handle_interrupt_84:
push rdi
mov rdi, 84
jmp handle_interrupt_

.global handle_interrupt_85
.align 32
handle_interrupt_85:
push rdi
mov rdi, 85
jmp handle_interrupt_

.global handle_interrupt_86
.align 32
handle_interrupt_86:
push rdi
mov rdi, 86
jmp handle_interrupt_

.global handle_interrupt_87
.align 32
handle_interrupt_87:
push rdi
mov rdi, 87
jmp handle_interrupt_

.global handle_interrupt_88
.align 32
handle_interrupt_88:
push rdi
mov rdi, 88
jmp handle_interrupt_

.global handle_interrupt_89
.align 32
handle_interrupt_89:
push rdi
mov rdi, 89
jmp handle_interrupt_

.global handle_interrupt_90
.align 32
handle_interrupt_90:
push rdi
mov rdi, 90
jmp handle_interrupt_

.global handle_interrupt_91
.align 32
handle_interrupt_91:
push rdi
mov rdi, 91
jmp handle_interrupt_

.global handle_interrupt_92
.align 32
handle_interrupt_92:
push rdi
mov rdi, 92
jmp handle_interrupt_

.global handle_interrupt_93
.align 32
handle_interrupt_93:
push rdi
mov rdi, 93
jmp handle_interrupt_

.global handle_interrupt_94
.align 32
handle_interrupt_94:
push rdi
mov rdi, 94
jmp handle_interrupt_

.global handle_interrupt_95
.align 32
handle_interrupt_95:
push rdi
mov rdi, 95
jmp handle_interrupt_

.global handle_interrupt_96
.align 32
handle_interrupt_96:
push rdi
mov rdi, 96
jmp handle_interrupt_

.global handle_interrupt_97
.align 32
handle_interrupt_97:
push rdi
mov rdi, 97
jmp handle_interrupt_

.global handle_interrupt_98
.align 32
handle_interrupt_98:
push rdi
mov rdi, 98
jmp handle_interrupt_

.global handle_interrupt_99
.align 32
handle_interrupt_99:
push rdi
mov rdi, 99
jmp handle_interrupt_

.global handle_interrupt_100
.align 32
handle_interrupt_100:
push rdi
mov rdi, 100
jmp handle_interrupt_

.global handle_interrupt_101
.align 32
handle_interrupt_101:
push rdi
mov rdi, 101
jmp handle_interrupt_

.global handle_interrupt_102
.align 32
handle_interrupt_102:
push rdi
mov rdi, 102
jmp handle_interrupt_

.global handle_interrupt_103
.align 32
handle_interrupt_103:
push rdi
mov rdi, 103
jmp handle_interrupt_

.global handle_interrupt_104
.align 32
handle_interrupt_104:
push rdi
mov rdi, 104
jmp handle_interrupt_

.global handle_interrupt_105
.align 32
handle_interrupt_105:
push rdi
mov rdi, 105
jmp handle_interrupt_

.global handle_interrupt_106
.align 32
handle_interrupt_106:
push rdi
mov rdi, 106
jmp handle_interrupt_

.global handle_interrupt_107
.align 32
handle_interrupt_107:
push rdi
mov rdi, 107
jmp handle_interrupt_

.global handle_interrupt_108
.align 32
handle_interrupt_108:
push rdi
mov rdi, 108
jmp handle_interrupt_

.global handle_interrupt_109
.align 32
handle_interrupt_109:
push rdi
mov rdi, 109
jmp handle_interrupt_

.global handle_interrupt_110
.align 32
handle_interrupt_110:
push rdi
mov rdi, 110
jmp handle_interrupt_

.global handle_interrupt_111
.align 32
handle_interrupt_111:
push rdi
mov rdi, 111
jmp handle_interrupt_

.global handle_interrupt_112
.align 32
handle_interrupt_112:
push rdi
mov rdi, 112
jmp handle_interrupt_

.global handle_interrupt_113
.align 32
handle_interrupt_113:
push rdi
mov rdi, 113
jmp handle_interrupt_

.global handle_interrupt_114
.align 32
handle_interrupt_114:
push rdi
mov rdi, 114
jmp handle_interrupt_

.global handle_interrupt_115
.align 32
handle_interrupt_115:
push rdi
mov rdi, 115
jmp handle_interrupt_

.global handle_interrupt_116
.align 32
handle_interrupt_116:
push rdi
mov rdi, 116
jmp handle_interrupt_

.global handle_interrupt_117
.align 32
handle_interrupt_117:
push rdi
mov rdi, 117
jmp handle_interrupt_

.global handle_interrupt_118
.align 32
handle_interrupt_118:
push rdi
mov rdi, 118
jmp handle_interrupt_

.global handle_interrupt_119
.align 32
handle_interrupt_119:
push rdi
mov rdi, 119
jmp handle_interrupt_

.global handle_interrupt_120
.align 32
handle_interrupt_120:
push rdi
mov rdi, 120
jmp handle_interrupt_

.global handle_interrupt_121
.align 32
handle_interrupt_121:
push rdi
mov rdi, 121
jmp handle_interrupt_

.global handle_interrupt_122
.align 32
handle_interrupt_122:
push rdi
mov rdi, 122
jmp handle_interrupt_

.global handle_interrupt_123
.align 32
handle_interrupt_123:
push rdi
mov rdi, 123
jmp handle_interrupt_

.global handle_interrupt_124
.align 32
handle_interrupt_124:
push rdi
mov rdi, 124
jmp handle_interrupt_

.global handle_interrupt_125
.align 32
handle_interrupt_125:
push rdi
mov rdi, 125
jmp handle_interrupt_

.global handle_interrupt_126
.align 32
handle_interrupt_126:
push rdi
mov rdi, 126
jmp handle_interrupt_

.global handle_interrupt_127
.align 32
handle_interrupt_127:
push rdi
mov rdi, 127
jmp handle_interrupt_

.global handle_interrupt_128
.align 32
handle_interrupt_128:
push rdi
mov rdi, 128
jmp handle_interrupt_

.global handle_interrupt_129
.align 32
handle_interrupt_129:
push rdi
mov rdi, 129
jmp handle_interrupt_

.global handle_interrupt_130
.align 32
handle_interrupt_130:
push rdi
mov rdi, 130
jmp handle_interrupt_

.global handle_interrupt_131
.align 32
handle_interrupt_131:
push rdi
mov rdi, 131
jmp handle_interrupt_

.global handle_interrupt_132
.align 32
handle_interrupt_132:
push rdi
mov rdi, 132
jmp handle_interrupt_

.global handle_interrupt_133
.align 32
handle_interrupt_133:
push rdi
mov rdi, 133
jmp handle_interrupt_

.global handle_interrupt_134
.align 32
handle_interrupt_134:
push rdi
mov rdi, 134
jmp handle_interrupt_

.global handle_interrupt_135
.align 32
handle_interrupt_135:
push rdi
mov rdi, 135
jmp handle_interrupt_

.global handle_interrupt_136
.align 32
handle_interrupt_136:
push rdi
mov rdi, 136
jmp handle_interrupt_

.global handle_interrupt_137
.align 32
handle_interrupt_137:
push rdi
mov rdi, 137
jmp handle_interrupt_

.global handle_interrupt_138
.align 32
handle_interrupt_138:
push rdi
mov rdi, 138
jmp handle_interrupt_

.global handle_interrupt_139
.align 32
handle_interrupt_139:
push rdi
mov rdi, 139
jmp handle_interrupt_

.global handle_interrupt_140
.align 32
handle_interrupt_140:
push rdi
mov rdi, 140
jmp handle_interrupt_

.global handle_interrupt_141
.align 32
handle_interrupt_141:
push rdi
mov rdi, 141
jmp handle_interrupt_

.global handle_interrupt_142
.align 32
handle_interrupt_142:
push rdi
mov rdi, 142
jmp handle_interrupt_

.global handle_interrupt_143
.align 32
handle_interrupt_143:
push rdi
mov rdi, 143
jmp handle_interrupt_

.global handle_interrupt_144
.align 32
handle_interrupt_144:
push rdi
mov rdi, 144
jmp handle_interrupt_

.global handle_interrupt_145
.align 32
handle_interrupt_145:
push rdi
mov rdi, 145
jmp handle_interrupt_

.global handle_interrupt_146
.align 32
handle_interrupt_146:
push rdi
mov rdi, 146
jmp handle_interrupt_

.global handle_interrupt_147
.align 32
handle_interrupt_147:
push rdi
mov rdi, 147
jmp handle_interrupt_

.global handle_interrupt_148
.align 32
handle_interrupt_148:
push rdi
mov rdi, 148
jmp handle_interrupt_

.global handle_interrupt_149
.align 32
handle_interrupt_149:
push rdi
mov rdi, 149
jmp handle_interrupt_

.global handle_interrupt_150
.align 32
handle_interrupt_150:
push rdi
mov rdi, 150
jmp handle_interrupt_

.global handle_interrupt_151
.align 32
handle_interrupt_151:
push rdi
mov rdi, 151
jmp handle_interrupt_

.global handle_interrupt_152
.align 32
handle_interrupt_152:
push rdi
mov rdi, 152
jmp handle_interrupt_

.global handle_interrupt_153
.align 32
handle_interrupt_153:
push rdi
mov rdi, 153
jmp handle_interrupt_

.global handle_interrupt_154
.align 32
handle_interrupt_154:
push rdi
mov rdi, 154
jmp handle_interrupt_

.global handle_interrupt_155
.align 32
handle_interrupt_155:
push rdi
mov rdi, 155
jmp handle_interrupt_

.global handle_interrupt_156
.align 32
handle_interrupt_156:
push rdi
mov rdi, 156
jmp handle_interrupt_

.global handle_interrupt_157
.align 32
handle_interrupt_157:
push rdi
mov rdi, 157
jmp handle_interrupt_

.global handle_interrupt_158
.align 32
handle_interrupt_158:
push rdi
mov rdi, 158
jmp handle_interrupt_

.global handle_interrupt_159
.align 32
handle_interrupt_159:
push rdi
mov rdi, 159
jmp handle_interrupt_

.global handle_interrupt_160
.align 32
handle_interrupt_160:
push rdi
mov rdi, 160
jmp handle_interrupt_

.global handle_interrupt_161
.align 32
handle_interrupt_161:
push rdi
mov rdi, 161
jmp handle_interrupt_

.global handle_interrupt_162
.align 32
handle_interrupt_162:
push rdi
mov rdi, 162
jmp handle_interrupt_

.global handle_interrupt_163
.align 32
handle_interrupt_163:
push rdi
mov rdi, 163
jmp handle_interrupt_

.global handle_interrupt_164
.align 32
handle_interrupt_164:
push rdi
mov rdi, 164
jmp handle_interrupt_

.global handle_interrupt_165
.align 32
handle_interrupt_165:
push rdi
mov rdi, 165
jmp handle_interrupt_

.global handle_interrupt_166
.align 32
handle_interrupt_166:
push rdi
mov rdi, 166
jmp handle_interrupt_

.global handle_interrupt_167
.align 32
handle_interrupt_167:
push rdi
mov rdi, 167
jmp handle_interrupt_

.global handle_interrupt_168
.align 32
handle_interrupt_168:
push rdi
mov rdi, 168
jmp handle_interrupt_

.global handle_interrupt_169
.align 32
handle_interrupt_169:
push rdi
mov rdi, 169
jmp handle_interrupt_

.global handle_interrupt_170
.align 32
handle_interrupt_170:
push rdi
mov rdi, 170
jmp handle_interrupt_

.global handle_interrupt_171
.align 32
handle_interrupt_171:
push rdi
mov rdi, 171
jmp handle_interrupt_

.global handle_interrupt_172
.align 32
handle_interrupt_172:
push rdi
mov rdi, 172
jmp handle_interrupt_

.global handle_interrupt_173
.align 32
handle_interrupt_173:
push rdi
mov rdi, 173
jmp handle_interrupt_

.global handle_interrupt_174
.align 32
handle_interrupt_174:
push rdi
mov rdi, 174
jmp handle_interrupt_

.global handle_interrupt_175
.align 32
handle_interrupt_175:
push rdi
mov rdi, 175
jmp handle_interrupt_

.global handle_interrupt_176
.align 32
handle_interrupt_176:
push rdi
mov rdi, 176
jmp handle_interrupt_

.global handle_interrupt_177
.align 32
handle_interrupt_177:
push rdi
mov rdi, 177
jmp handle_interrupt_

.global handle_interrupt_178
.align 32
handle_interrupt_178:
push rdi
mov rdi, 178
jmp handle_interrupt_

.global handle_interrupt_179
.align 32
handle_interrupt_179:
push rdi
mov rdi, 179
jmp handle_interrupt_

.global handle_interrupt_180
.align 32
handle_interrupt_180:
push rdi
mov rdi, 180
jmp handle_interrupt_

.global handle_interrupt_181
.align 32
handle_interrupt_181:
push rdi
mov rdi, 181
jmp handle_interrupt_

.global handle_interrupt_182
.align 32
handle_interrupt_182:
push rdi
mov rdi, 182
jmp handle_interrupt_

.global handle_interrupt_183
.align 32
handle_interrupt_183:
push rdi
mov rdi, 183
jmp handle_interrupt_

.global handle_interrupt_184
.align 32
handle_interrupt_184:
push rdi
mov rdi, 184
jmp handle_interrupt_

.global handle_interrupt_185
.align 32
handle_interrupt_185:
push rdi
mov rdi, 185
jmp handle_interrupt_

.global handle_interrupt_186
.align 32
handle_interrupt_186:
push rdi
mov rdi, 186
jmp handle_interrupt_

.global handle_interrupt_187
.align 32
handle_interrupt_187:
push rdi
mov rdi, 187
jmp handle_interrupt_

.global handle_interrupt_188
.align 32
handle_interrupt_188:
push rdi
mov rdi, 188
jmp handle_interrupt_

.global handle_interrupt_189
.align 32
handle_interrupt_189:
push rdi
mov rdi, 189
jmp handle_interrupt_

.global handle_interrupt_190
.align 32
handle_interrupt_190:
push rdi
mov rdi, 190
jmp handle_interrupt_

.global handle_interrupt_191
.align 32
handle_interrupt_191:
push rdi
mov rdi, 191
jmp handle_interrupt_

.global handle_interrupt_192
.align 32
handle_interrupt_192:
push rdi
mov rdi, 192
jmp handle_interrupt_

.global handle_interrupt_193
.align 32
handle_interrupt_193:
push rdi
mov rdi, 193
jmp handle_interrupt_

.global handle_interrupt_194
.align 32
handle_interrupt_194:
push rdi
mov rdi, 194
jmp handle_interrupt_

.global handle_interrupt_195
.align 32
handle_interrupt_195:
push rdi
mov rdi, 195
jmp handle_interrupt_

.global handle_interrupt_196
.align 32
handle_interrupt_196:
push rdi
mov rdi, 196
jmp handle_interrupt_

.global handle_interrupt_197
.align 32
handle_interrupt_197:
push rdi
mov rdi, 197
jmp handle_interrupt_

.global handle_interrupt_198
.align 32
handle_interrupt_198:
push rdi
mov rdi, 198
jmp handle_interrupt_

.global handle_interrupt_199
.align 32
handle_interrupt_199:
push rdi
mov rdi, 199
jmp handle_interrupt_

.global handle_interrupt_200
.align 32
handle_interrupt_200:
push rdi
mov rdi, 200
jmp handle_interrupt_

.global handle_interrupt_201
.align 32
handle_interrupt_201:
push rdi
mov rdi, 201
jmp handle_interrupt_

.global handle_interrupt_202
.align 32
handle_interrupt_202:
push rdi
mov rdi, 202
jmp handle_interrupt_

.global handle_interrupt_203
.align 32
handle_interrupt_203:
push rdi
mov rdi, 203
jmp handle_interrupt_

.global handle_interrupt_204
.align 32
handle_interrupt_204:
push rdi
mov rdi, 204
jmp handle_interrupt_

.global handle_interrupt_205
.align 32
handle_interrupt_205:
push rdi
mov rdi, 205
jmp handle_interrupt_

.global handle_interrupt_206
.align 32
handle_interrupt_206:
push rdi
mov rdi, 206
jmp handle_interrupt_

.global handle_interrupt_207
.align 32
handle_interrupt_207:
push rdi
mov rdi, 207
jmp handle_interrupt_

.global handle_interrupt_208
.align 32
handle_interrupt_208:
push rdi
mov rdi, 208
jmp handle_interrupt_

.global handle_interrupt_209
.align 32
handle_interrupt_209:
push rdi
mov rdi, 209
jmp handle_interrupt_

.global handle_interrupt_210
.align 32
handle_interrupt_210:
push rdi
mov rdi, 210
jmp handle_interrupt_

.global handle_interrupt_211
.align 32
handle_interrupt_211:
push rdi
mov rdi, 211
jmp handle_interrupt_

.global handle_interrupt_212
.align 32
handle_interrupt_212:
push rdi
mov rdi, 212
jmp handle_interrupt_

.global handle_interrupt_213
.align 32
handle_interrupt_213:
push rdi
mov rdi, 213
jmp handle_interrupt_

.global handle_interrupt_214
.align 32
handle_interrupt_214:
push rdi
mov rdi, 214
jmp handle_interrupt_

.global handle_interrupt_215
.align 32
handle_interrupt_215:
push rdi
mov rdi, 215
jmp handle_interrupt_

.global handle_interrupt_216
.align 32
handle_interrupt_216:
push rdi
mov rdi, 216
jmp handle_interrupt_

.global handle_interrupt_217
.align 32
handle_interrupt_217:
push rdi
mov rdi, 217
jmp handle_interrupt_

.global handle_interrupt_218
.align 32
handle_interrupt_218:
push rdi
mov rdi, 218
jmp handle_interrupt_

.global handle_interrupt_219
.align 32
handle_interrupt_219:
push rdi
mov rdi, 219
jmp handle_interrupt_

.global handle_interrupt_220
.align 32
handle_interrupt_220:
push rdi
mov rdi, 220
jmp handle_interrupt_

.global handle_interrupt_221
.align 32
handle_interrupt_221:
push rdi
mov rdi, 221
jmp handle_interrupt_

.global handle_interrupt_222
.align 32
handle_interrupt_222:
push rdi
mov rdi, 222
jmp handle_interrupt_

.global handle_interrupt_223
.align 32
handle_interrupt_223:
push rdi
mov rdi, 223
jmp handle_interrupt_

.global handle_interrupt_224
.align 32
handle_interrupt_224:
push rdi
mov rdi, 224
jmp handle_interrupt_

.global handle_interrupt_225
.align 32
handle_interrupt_225:
push rdi
mov rdi, 225
jmp handle_interrupt_

.global handle_interrupt_226
.align 32
handle_interrupt_226:
push rdi
mov rdi, 226
jmp handle_interrupt_

.global handle_interrupt_227
.align 32
handle_interrupt_227:
push rdi
mov rdi, 227
jmp handle_interrupt_

.global handle_interrupt_228
.align 32
handle_interrupt_228:
push rdi
mov rdi, 228
jmp handle_interrupt_

.global handle_interrupt_229
.align 32
handle_interrupt_229:
push rdi
mov rdi, 229
jmp handle_interrupt_

.global handle_interrupt_230
.align 32
handle_interrupt_230:
push rdi
mov rdi, 230
jmp handle_interrupt_

.global handle_interrupt_231
.align 32
handle_interrupt_231:
push rdi
mov rdi, 231
jmp handle_interrupt_

.global handle_interrupt_232
.align 32
handle_interrupt_232:
push rdi
mov rdi, 232
jmp handle_interrupt_

.global handle_interrupt_233
.align 32
handle_interrupt_233:
push rdi
mov rdi, 233
jmp handle_interrupt_

.global handle_interrupt_234
.align 32
handle_interrupt_234:
push rdi
mov rdi, 234
jmp handle_interrupt_

.global handle_interrupt_235
.align 32
handle_interrupt_235:
push rdi
mov rdi, 235
jmp handle_interrupt_

.global handle_interrupt_236
.align 32
handle_interrupt_236:
push rdi
mov rdi, 236
jmp handle_interrupt_

.global handle_interrupt_237
.align 32
handle_interrupt_237:
push rdi
mov rdi, 237
jmp handle_interrupt_

.global handle_interrupt_238
.align 32
handle_interrupt_238:
push rdi
mov rdi, 238
jmp handle_interrupt_

.global handle_interrupt_239
.align 32
handle_interrupt_239:
push rdi
mov rdi, 239
jmp handle_interrupt_

.global handle_interrupt_240
.align 32
handle_interrupt_240:
push rdi
mov rdi, 240
jmp handle_interrupt_

.global handle_interrupt_241
.align 32
handle_interrupt_241:
push rdi
mov rdi, 241
jmp handle_interrupt_

.global handle_interrupt_242
.align 32
handle_interrupt_242:
push rdi
mov rdi, 242
jmp handle_interrupt_

.global handle_interrupt_243
.align 32
handle_interrupt_243:
push rdi
mov rdi, 243
jmp handle_interrupt_

.global handle_interrupt_244
.align 32
handle_interrupt_244:
push rdi
mov rdi, 244
jmp handle_interrupt_

.global handle_interrupt_245
.align 32
handle_interrupt_245:
push rdi
mov rdi, 245
jmp handle_interrupt_

.global handle_interrupt_246
.align 32
handle_interrupt_246:
push rdi
mov rdi, 246
jmp handle_interrupt_

.global handle_interrupt_247
.align 32
handle_interrupt_247:
push rdi
mov rdi, 247
jmp handle_interrupt_

.global handle_interrupt_248
.align 32
handle_interrupt_248:
push rdi
mov rdi, 248
jmp handle_interrupt_

.global handle_interrupt_249
.align 32
handle_interrupt_249:
push rdi
mov rdi, 249
jmp handle_interrupt_

.global handle_interrupt_250
.align 32
handle_interrupt_250:
push rdi
mov rdi, 250
jmp handle_interrupt_

.global handle_interrupt_251
.align 32
handle_interrupt_251:
push rdi
mov rdi, 251
jmp handle_interrupt_

.global handle_interrupt_252
.align 32
handle_interrupt_252:
push rdi
mov rdi, 252
jmp handle_interrupt_

.global handle_interrupt_253
.align 32
handle_interrupt_253:
push rdi
mov rdi, 253
jmp handle_interrupt_

.global handle_interrupt_254
.align 32
handle_interrupt_254:
push rdi
mov rdi, 254
jmp handle_interrupt_

.global handle_interrupt_255
.align 32
handle_interrupt_255:
push rdi
mov rdi, 255
jmp handle_interrupt_


text:
/*  multiboot2.h - Multiboot 2 header file.  */
/*  Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to
 *  deal in the Software without restriction, including without limitation the
 *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 *  sell copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
 *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef MULTIBOOT_HEADER
#define MULTIBOOT_HEADER 1

/* How many bytes from the start of the file we search for the header.  */
#define MULTIBOOT_SEARCH			32768
#define MULTIBOOT_HEADER_ALIGN			8

/* The magic field should contain this.  */
#define MULTIBOOT2_HEADER_MAGIC			0xe85250d6

/* This should be in %eax.  */
#define MULTIBOOT2_BOOTLOADER_MAGIC		0x36d76289

/* Alignment of multiboot modules.  */
#define MULTIBOOT_MOD_ALIGN			0x00001000

/* Alignment of the multiboot info structure.  */
#define MULTIBOOT_INFO_ALIGN			0x00000008

/* Flags set in the 'flags' member of the multiboot header.  */

#define MULTIBOOT_TAG_ALIGN                  8
#define MULTIBOOT_TAG_TYPE_END               0
#define MULTIBOOT_TAG_TYPE_CMDLINE           1
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME  2
#define MULTIBOOT_TAG_TYPE_MODULE            3
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO     4
#define MULTIBOOT_TAG_TYPE_BOOTDEV           5
#define MULTIBOOT_TAG_TYPE_MMAP              6
#define MULTIBOOT_TAG_TYPE_VBE               7
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER       8
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS      9
#define MULTIBOOT_TAG_TYPE_APM               10
#define MULTIBOOT_TAG_TYPE_EFI32             11
#define MULTIBOOT_TAG_TYPE_EFI64             12
#define MULTIBOOT_TAG_TYPE_SMBIOS            13
#define MULTIBOOT_TAG_TYPE_ACPI_OLD          14
#define MULTIBOOT_TAG_TYPE_ACPI_NEW          15
#define MULTIBOOT_TAG_TYPE_NETWORK           16
#define MULTIBOOT_TAG_TYPE_EFI_MMAP          17
#define MULTIBOOT_TAG_TYPE_EFI_BS            18

#define MULTIBOOT_HEADER_TAG_END  0
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST  1
#define MULTIBOOT_HEADER_TAG_ADDRESS  2
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS  3
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS  4
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER  5
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN  6
#define MULTIBOOT_HEADER_TAG_EFI_BS  7

#define MULTIBOOT_ARCHITECTURE_I386  0
#define MULTIBOOT_ARCHITECTURE_MIPS32  4
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1

#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2

#ifndef ASM_FILE

typedef unsigned char		multiboot_uint8_t;
typedef unsigned short		multiboot_uint16_t;
typedef unsigned int		multiboot_uint32_t;
typedef unsigned long long	multiboot_uint64_t;

struct multiboot_header
{
  /* Must be MULTIBOOT_MAGIC - see above.  */
  multiboot_uint32_t magic;

  /* ISA */
  multiboot_uint32_t architecture;

  /* Total header length.  */
  multiboot_uint32_t header_length;

  /* The above fields plus this one must equal 0 mod 2^32. */
  multiboot_uint32_t checksum;
};

struct multiboot_header_tag
{
  multiboot_uint16_t type;
  multiboot_uint16_t flags;
  multiboot_uint32_t size;
};

struct multiboot_header_tag_information_request
{
  multiboot_uint16_t type;
  multiboot_uint16_t flags;
  multiboot_uint32_t size;
  multiboot_uint32_t requests[0];
};

struct multiboot_header_tag_address
{
  multiboot_uint16_t type;
  multiboot_uint16_t flags;
  multiboot_uint32_t size;
  multiboot_uint32_t header_addr;
  multiboot_uint32_t load_addr;
  multiboot_uint32_t load_end_addr;
  multiboot_uint32_t bss_end_addr;
};

struct multiboot_header_tag_entry_address
{
  multiboot_uint16_t type;
  multiboot_uint16_t flags;
  multiboot_uint32_t size;
  multiboot_uint32_t entry_addr;
};

struct multiboot_header_tag_console_flags
{
  multiboot_uint16_t type;
  multiboot_uint16_t flags;
  multiboot_uint32_t size;
  multiboot_uint32_t console_flags;
};

struct multiboot_header_tag_framebuffer
{
  multiboot_uint16_t type;
  multiboot_uint16_t flags;
  multiboot_uint32_t size;
  multiboot_uint32_t width;
  multiboot_uint32_t height;
  multiboot_uint32_t depth;
};

struct multiboot_header_tag_module_align
{
  multiboot_uint16_t type;
  multiboot_uint16_t flags;
  multiboot_uint32_t size;
  multiboot_uint32_t width;
  multiboot_uint32_t height;
  multiboot_uint32_t depth;
};

struct multiboot_color
{
  multiboot_uint8_t red;
  multiboot_uint8_t green;
  multiboot_uint8_t blue;
};

struct multiboot_mmap_entry
{
  multiboot_uint64_t addr;
  multiboot_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE		1
#define MULTIBOOT_MEMORY_RESERVED		2
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
#define MULTIBOOT_MEMORY_NVS                    4
#define MULTIBOOT_MEMORY_BADRAM                 5
  multiboot_uint32_t type;
  multiboot_uint32_t zero;
} GRUB_PACKED;
typedef struct multiboot_mmap_entry multiboot_memory_map_t;

struct multiboot_tag
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
};

struct multiboot_tag_string
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  char string[0];
};

struct multiboot_tag_module
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint32_t mod_start;
  multiboot_uint32_t mod_end;
  char cmdline[0];
};

struct multiboot_tag_basic_meminfo
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint32_t mem_lower;
  multiboot_uint32_t mem_upper;
};

struct multiboot_tag_bootdev
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint32_t biosdev;
  multiboot_uint32_t slice;
  multiboot_uint32_t part;
};

struct multiboot_tag_mmap
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint32_t entry_size;
  multiboot_uint32_t entry_version;
  struct multiboot_mmap_entry entries[0];
};

struct multiboot_vbe_info_block
{
  multiboot_uint8_t external_specification[512];
};

struct multiboot_vbe_mode_info_block
{
  multiboot_uint8_t external_specification[256];
};

struct multiboot_tag_vbe
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;

  multiboot_uint16_t vbe_mode;
  multiboot_uint16_t vbe_interface_seg;
  multiboot_uint16_t vbe_interface_off;
  multiboot_uint16_t vbe_interface_len;

  struct multiboot_vbe_info_block vbe_control_info;
  struct multiboot_vbe_mode_info_block vbe_mode_info;
};

struct multiboot_tag_framebuffer_common
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;

  multiboot_uint64_t framebuffer_addr;
  multiboot_uint32_t framebuffer_pitch;
  multiboot_uint32_t framebuffer_width;
  multiboot_uint32_t framebuffer_height;
  multiboot_uint8_t framebuffer_bpp;
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT	2
  multiboot_uint8_t framebuffer_type;
  multiboot_uint16_t reserved;
};

struct multiboot_tag_framebuffer
{
  struct multiboot_tag_framebuffer_common common;

  union
  {
    struct
    {
      multiboot_uint16_t framebuffer_palette_num_colors;
      struct multiboot_color framebuffer_palette[0];
    };
    struct
    {
      multiboot_uint8_t framebuffer_red_field_position;
      multiboot_uint8_t framebuffer_red_mask_size;
      multiboot_uint8_t framebuffer_green_field_position;
      multiboot_uint8_t framebuffer_green_mask_size;
      multiboot_uint8_t framebuffer_blue_field_position;
      multiboot_uint8_t framebuffer_blue_mask_size;
    };
  };
};

struct multiboot_tag_elf_sections
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint32_t num;
  multiboot_uint32_t entsize;
  multiboot_uint32_t shndx;
  char sections[0];
};

struct multiboot_tag_apm
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint16_t version;
  multiboot_uint16_t cseg;
  multiboot_uint32_t offset;
  multiboot_uint16_t cseg_16;
  multiboot_uint16_t dseg;
  multiboot_uint16_t flags;
  multiboot_uint16_t cseg_len;
  multiboot_uint16_t cseg_16_len;
  multiboot_uint16_t dseg_len;
};

struct multiboot_tag_efi32
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint32_t pointer;
};

struct multiboot_tag_efi64
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint64_t pointer;
};

struct multiboot_tag_smbios
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint8_t major;
  multiboot_uint8_t minor;
  multiboot_uint8_t reserved[6];
  multiboot_uint8_t tables[0];
};

struct multiboot_tag_old_acpi
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint8_t rsdp[0];
};

struct multiboot_tag_new_acpi
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint8_t rsdp[0];
};

struct multiboot_tag_network
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint8_t dhcpack[0];
};

struct multiboot_tag_efi_mmap
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint32_t descr_size;
  multiboot_uint32_t descr_vers;
  multiboot_uint8_t efi_mmap[0];
};

#endif /* ! ASM_FILE */

#endif /* ! MULTIBOOT_HEADER */

repo_language: C

mime_type: text/x-c


text:
.intel_syntax noprefix
.code32

#define ASM_FILE 1
#include "multiboot2.h"

#define trap xchg bx, bx

.bss

// align for movaps
.align 16
stack_end: .space 4096 * 1 * 1024
stack:

.data

.align 8
// Global Descriptor Table
GDT:
  GDTNull:
  .quad 0
  GDTCode:
  .short 0xFFFF
  .short 0
  .byte 0
  .byte 0x9a
  .byte 0xaf
  .byte 0
  GDTData:
  .short 0xFFFF
  .short 0
  .byte 0
  .byte 0x92
  .byte 0x8f
  .byte 0
GDT_end:
  GDTPointer:
  .short GDT_end - GDT - 1
  .quad GDT

.align 4
.global multiboot_boot_information
multiboot_boot_information: .long 0

.text
.global start
.align 4
multiboot_header:
  .long MULTIBOOT2_HEADER_MAGIC
  .long MULTIBOOT_ARCHITECTURE_I386
  # length
  .long multiboot_header_end - multiboot_header
  # checksum
  .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header))
.align 8
multiboot_framebuffer:
  .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
  .short MULTIBOOT_HEADER_TAG_OPTIONAL
  .long multiboot_framebuffer_end - multiboot_framebuffer
  .long 0#1920
  .long 0#1080
  .long 32
.align 4
multiboot_framebuffer_end:
  .short MULTIBOOT_HEADER_TAG_END
  .short MULTIBOOT_TAG_TYPE_END
  .long 0
multiboot_header_end:
.align 4
start:
enter_long_mode:
  // disable interrupts
  cli

  // ebx contains multiboot2 data structure from GRUB
  mov multiboot_boot_information, ebx

  // enable SSE
  mov ecx, cr0
  // clear CR0.EM bit
  btr ecx, 2
  // set CR0.MP bit
  bts ecx, 1
  mov cr0, ecx
  mov ecx, cr4
  // set CR4.OSFXSR bit
  bts ecx, 9
  // set CR4.OSXMMEXCPT bit
  bts ecx, 10
  mov cr4, ecx

  # Enable PAE
  mov eax, cr4
  or eax, 1 << 5
  mov cr4, eax

  # Enable long mode and syscalls
  // EFER
  mov ecx, 0xc0000080
  rdmsr
  //long mode and syscalls
  //or eax, 0x101
  // long mode only
  or eax, 0x100
  wrmsr

  // push grows the stack down
  lea esp, stack
  call setup_page_table

  # Enable paging
  mov eax, cr0
  or eax, 0x80000000
  mov cr0, eax

  # Load the long mode GDT.
  lgdt [GDTPointer]
  call setup_IDT
  lidt [IDTR]

  // jump to the 64-bit code segment located at 0x08, as indicated in the GDT
  jmp 0x08:Realm64

.code64
Realm64:
  // "4.5.3 Segment Registers in 64-Bit Mode"
  // "In 64-bit mode, the contents of the ES, DS, and SS segment registers are ignored."
  mov ax, 0
  mov ds, ax
  mov es, ax
  mov fs, ax
  mov gs, ax
  mov ss, ax

// http://www.brokenthorn.com/Resources/OSDevPic.html
// http://www.brokenthorn.com/Resources/OSDev16.html
// https://github.com/haiku/haiku/blob/5e726ed/src/system/kernel/arch/x86/pic.cpp#L219

#define PIC1_CMD_STATUS 0x20
#define PIC1_IMR_DATA 0x21
#define PIC2_CMD_STATUS 0xa0
#define PIC2_IMR_DATA 0xa1

  // ICW 1
  // initialization bits:
  // 5-7: 0 unused
  // 4:   1 initialization
  // 3:   0 edge triggered
  // 2:   0 ignored by x86
  // 1:   0 cascading
  // 0:   1 IC4 expected
  mov al, 0b00010001
  out PIC1_CMD_STATUS, al
  out PIC2_CMD_STATUS, al

  // ICW 2
  // remap base IRQ addresses outside reserved range
  mov al, 0x20
  out PIC1_IMR_DATA, al
  mov al, 0x28
  out PIC2_IMR_DATA, al

  // ICW 3
  // enable cascading with PIC2 at IRQ 2
  mov al, 4
  out PIC1_IMR_DATA, al
  mov al, 2
  out PIC2_IMR_DATA, al

  // ICW 4
  // 5-7: 0 reserved
  // 4:   0 Special Fully Nested Mode
  // 3:   0 buffered mode off
  // 2:   0 buffered mode off
  // 1:   0 auto EOI off
  // 0:   1 8086 mode
  mov al, 0x1
  out PIC1_IMR_DATA, al
  out PIC2_IMR_DATA, al

#if 1
  // configure PIT for 100 Hz
  mov al, 0x36
  out 0x43, al
  mov al, 0xa9
  out 0x40, al
  mov al, 0x04
  out 0x40, al
#endif

#if 1
  // write IMR
  // IRQ 2 PIC2
  // IRQ 1 keyboard
  // IRQ 0 timer
  mov al, 0b11111000
  out PIC1_IMR_DATA, al

  // mouse is on PIC2
  // IRQ 12 mouse
  mov al, 0b11101111
  //mov al, 0b11111111
  out PIC2_IMR_DATA, al
#endif

#undef PIC1_CMD
#undef PIC1_DATA
#undef PIC2_CMD
#undef PIC2_DATA

  // enable FPU
  fninit
  push 0x037f
  fldcw [rsp]
  pop rax

  // enable interrupts
  sti

  call main
  hlt

// "8.9.3 Interrupt Stack Frame"
#include "interrupt.S"

// http://www.brokenthorn.com/Resources/OSDev15.html
// http://svnweb.freebsd.org/base/head/sys/amd64/amd64/exception.S?view=co
// http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/arch/amd64/amd64/vector.S?rev=1.43&content-type=text/plain
// https://github.com/ReturnInfinity/BareMetal-kernel/blob/master/src/x86-64/interrupt.asm

.global handle_interrupt_
handle_interrupt_:
  push rax
  push rbx
  push rbp
  push rcx
  push rdx
  push rsi
  // saved in the individual handlers
  //push rdi
  push r8
  push r9
  push r10
  push r11
  push r12
  push r13
  push r14
  push r15
  push fs
  push gs

  // no need to save all the segment registers since this is 64-bit mode only

  // NOTE: RSP is +48 with error code
  // but only +40 without error code

  call handle_interrupt

  // FIXME: need to pop error code if there is a error.
  // iretq pops RIP, CS, RFLAGS, RSP, and SS

  pop gs
  pop fs
  pop r15
  pop r14
  pop r13
  pop r12
  pop r11
  pop r10
  pop r9
  pop r8
  pop rsi
  pop rdx
  pop rcx
  pop rbp
  pop rbx
  pop rax
  // set in the individual handlers
  pop rdi

  iretq

.global outb
outb:
  mov rdx, rdi
  mov rax, rsi
  outb dx, al
  ret

.global inb
inb:
  mov rdx, rdi
  inb al, dx
  //mov rdi, rax
  ret


text:
local sqlite3 = require("lsqlite3")

package.searchers[2] = function(modname)
  return loader, modname
end

timer_ticks = 0

local tasks = {}

function taskadd(func, name, maskcount)
  local co = coroutine.create(func)
  setmaskhook(co, maskcount or 1000)
  local task = {
    name = name or "task_" .. #tasks,
    -- For restarting the task if it crashes.
    func = func,
    wait_until = 0,
    co = co,
  }
  table.insert(tasks, task)
  return task
end

-- file system
local fs = {}

fs["/dev/null"] =
{
  buf = "",
  fd = {},
  write = function(fd, buf)
    return #buf
  end,
  read = function(fd, count)
    return count
  end,
}

fs["/dev/urandom"] =
{
  buf = "",
  fd = {},
  write = function(fd, buf)
    return #buf
  end,
  read = function(fd, count)
    return count
  end,
}

local O_CREAT = 64
local O_APPEND = 1024

function open(pathname, flags, mode)
  if fs[pathname] == nil and bit32.band(flags, O_CREAT) ~= O_CREAT then
    return -1
  end
  if fs[pathname] == nil and bit32.band(flags, O_CREAT) == O_CREAT then
    print("creat")
    -- create new file
    fs[pathname] =
    {
      buf = "",
      fd = {},
    }
  end
  local fd =
  {
    top = fs[pathname],
    -- string.sub considers the first character to be at position 1
    pos = 1
  }
  if fd == 1 then
    print("warning: fd == 1 -- conflicts with stdout")
  end
  if bit32.band(flags, O_APPEND) == O_CREAT then
    print("append")
    fd.pos = #fd.top.buf
  end
  table.insert(fs[pathname].fd, fd)
  return fd
end

local SEEK_SET = 0
local SEEK_CUR = 1
local SEEK_END = 2
function lseek(fd, offset, whence)
  if whence == SEEK_SET then
    fd.pos = offset + 1
  elseif whence == SEEK_CUR then
    fd.pos = fd.pos + offset
  elseif whence == SEEK_END then
    --~ fd.pos = #fd.top.buf
    return -1;
  else
    return -1
  end
  return fd.pos
end

local function sinsert(str, val, pos)
  local s1 = str:sub(0, pos)
  local s2 = str:sub(pos + 1)
  return s1 .. val .. s2
end

function read(fd, count)
  if fd.top.read then
    return fd.top.read(fd, count)
  end
  local buf = fd.top.buf:sub(fd.pos, fd.pos + count)
  print(buf)
  fd.pos = fd.pos + count
  return buf
end

local terminal_lines = {
  -- Start with one empty line.
  {}
}

local WRAP_X = (DISPLAY_WIDTH / 9)
local CLEAR_Y = (DISPLAY_HEIGHT / 15) - 1
local stdout = 1
function write(fd, buf)
  if fd == stdout then
    for c in buf:gmatch(".") do
      local line = terminal_lines[#terminal_lines]
      table.insert(line, c)
      if c == "\n" or #line >= WRAP_X then
        table.insert(terminal_lines, {})
      end
      if #terminal_lines >= CLEAR_Y then
        terminal_lines = {{}}
      end
    end
    return #buf
  end
  fd.top.buf = sinsert(fd.top.buf, buf, fd.pos)
  fd.pos = fd.pos + #buf
  return #buf
end

function hline(x1, y, x2, r, g, b)
  if x2 > x1 then
    for i = 0, x2 - x1, 1 do
      putpixel(x1 + i, y, r, g, b)
    end
  end
end

function vline(x, y1, y2, r, g, b)
  if y2 > y1 then
    for i = 0, y2 - y1, 1 do
      putpixel(x, y1 + i, r, g, b)
    end
  end
end

function rectangle(x, y, width, height, r, g, b)
  hline(x, y, x + width, r, g, b)
  hline(x, y + height, x + width, r, g, b)
  vline(x, y, y + height, r, g, b)
  vline(x + width, y, y + height, r, g, b)
end

local function wait(ticks)
  local me, main = coroutine.running()
  for _, task in ipairs(tasks) do
    if task.co == me then
      task.wait_until = timer_ticks + ticks
      break
    end
  end
  coroutine.yield()
end

local scancode2char =
{
  27, '1', '2', '3', '4', '5', '6', '7', {'8', '*'},	--[ 9 --]
  {'9', '('}, {'0', ')'}, {'-', '_'}, {'=', '+'}, '\b',	--[ Backspace --]
  '\t',			--[ Tab --]
  'q', 'w', 'e', 'r',	--[ 19 --]
  't', 'y', 'u', 'i', 'o', 'p', {'[', '{'}, {']', '}'}, '\n',	--[ Enter key --]
  0,			--[ 29   - Control --]
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', {';', ':'},	--[ 39 --]
  {'\'', '"'}, '`',   0,		--[ Left shift --]
  '\\', 'z', 'x', 'c', 'v', 'b', 'n',			--[ 49 --]
  'm', {',', '<'}, {'.', '>'}, '/',   0,				--[ Right shift --]
  '*',
  0,	--[ Alt --]
  ' ',	--[ Space bar --]
  0,	--[ Caps lock --]
  0,	--[ 59 - F1 key ... > --]
  0,   0,   0,   0,   0,   0,   0,   0,
  0,	--[ < ... F10 --]
  0,	--[ 69 - Num lock--]
  0,	--[ Scroll Lock --]
  0,	--[ Home key --]
  0,	--[ Up Arrow --]
  0,	--[ Page Up --]
  '-',
  0,	--[ Left Arrow --]
  0,
  0,	--[ Right Arrow --]
  '+',
  0,	--[ 79 - End key--]
  0,	--[ Down Arrow --]
  0,	--[ Page Down --]
  0,	--[ Insert Key --]
  0,	--[ Delete Key --]
  0,   0,   0,
  0,	--[ F11 Key --]
  0,	--[ F12 Key --]
  0,	--[ All other keys are undefined --]
}

local font = require("font")
function drawchar(x, y, character, r, g, b)
  local f = font[character]
  if f then
    local xl = 0
    local yl = 0
    for i = 1, #f do
      local c = f:sub(i, i)
      if c == '\n' then
        yl = yl + 1
        xl = 0
      elseif c == '.' then
        putpixel(x + xl, y + yl, r, g, b)
        xl = xl + 1
      elseif c == ' ' then
        putpixel(x + xl, y + yl, 0, 0, 0)
        xl = xl + 1
      end
    end
  end
end

function drawtext(x, y, text)
  text = tostring(text)
  local space = 0
  for i = 1, #text do
    local c = text:sub(i, i)
    if c == "\n" then
      space = 0
      y = y + 15
    end
    drawchar(x + space, y, c, 255, 255, 255)
    space = space + 8
  end
end

local tilda = false
local shift_on = 0
local ctrl_on = 0
function key_pressed(scancode_)
  if scancode_ == 0x2a or scancode_ == 0x36 then
    shift_on = 1
    return
  elseif scancode_ == 0xaa or scancode_ == 0xb6 then
    shift_on = 0
    return
  end
  if scancode_ == 0x1d then
    ctrl_on = 1
    return
  elseif scancode_ == 0x9d then
    ctrl_on = 0
    return
  end
  -- print(tostring(scancode_))
  local c = scancode2char[scancode_]
  if type(c) == "table" then
    c = c[shift_on + 1]
  end
  if type(c) == "string" then
    if c == '\b' then
      local line = terminal_lines[#terminal_lines]
      table.remove(line, #line)
    elseif c == '\n' then
      local line = terminal_lines[#terminal_lines]
      io.write("\n")
      local linestr = table.concat(line)
      local chunk, errmsg = load(linestr)
      if chunk == nil then
        print(errmsg)
      else
        local ok, err = pcall(function() chunk() end)
        if not ok then
          print(err)
        end
      end
    elseif ctrl_on == 1 and c == "l" then
      terminal_lines = {{}}
    elseif c == "`" then
      tilda = not tilda
    else
      local line = terminal_lines[#terminal_lines]
      if not line then
        line = {}
        terminal_lines[#terminal_lines + 1] = line
      end
      io.write(c)
      io.flush()
    end
  end
end

-- TODO: don't poll
local function keyboard_task()
  while 1 do
    local scancodes = get_keyboard_interrupt()
    for _, scancode in ipairs(scancodes) do
      key_pressed(scancode)
    end
    wait(5)
  end
end

local function red_rect_task()
  local red = 20
  while 1 do
    for i = 1, 4 do
      rectangle(DISPLAY_WIDTH - 420, 100, 100, 100, red, 0, 0)
      wait(5)
    end
    red = red + 1
    if red >= 255 then
      red = 20
    end
  end
end

local function green_rect_task()
  local green = 20
  while 1 do
    for i = 1, 6 do
      rectangle(DISPLAY_WIDTH - 410, 110, 100, 100, 0, green, 0)
      wait(5)
    end
    green = green + 3
    if green >= 255 then
      green = 20
    end
  end
end

local function blue_rect_task()
  local blue = 20
  while 1 do
    for i = 1, 8 do
      rectangle(DISPLAY_WIDTH - 400, 120, 100, 100, 0, 0, blue)
      wait(5)
    end
    blue = blue + 5
    if blue >= 255 then
      blue = 20
    end
  end
end

local function draw_tilda()
  -- Draw border.
  rectangle(4, 4, DISPLAY_WIDTH - 8, DISPLAY_HEIGHT - 8, 255, 0, 255)
end

local function draw_terminal()
  local pad_x = 10
  local pad_y = 15
  local cursor_x = 0
  local cursor_y = 1
  for y, line in ipairs(terminal_lines) do
    local str = table.concat(line)
    drawtext(pad_x, y * pad_y, str)
    cursor_x = #str
    cursor_y = y
  end
  -- Draw the terminal cursor.
  rectangle((cursor_x * 8) + pad_x, (cursor_y * pad_y) - 2, 1, 14, 255, 255, 255)
end

local function display_task()
  while 1 do
    -- Draw a border around the screen.
    rectangle(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1, 255, 255, 255)
    if tilda then
      draw_tilda()
    end

    -- Memory usage.
    local bytes_used = math.ceil(collectgarbage("count"))
    local message = ("memory usage: %u kilobytes     "):format(bytes_used)
    drawtext(DISPLAY_WIDTH - #message * 8, 150, message)

    draw_terminal()
    swap_buffers()
    wait(10)
  end
end

function fib(n)
  return n < 2 and n or fib(n - 1) + fib(n - 2)
end

taskadd(keyboard_task, "keyboard")
taskadd(display_task, "display")
taskadd(red_rect_task, "red_rect")
taskadd(green_rect_task, "green_rect")
taskadd(blue_rect_task, "blue_rect")

local function database_open()
  db = sqlite3.open_memory()
  db:exec([[
  CREATE TABLE test (id INTEGER PRIMARY KEY, data TEXT);
  INSERT INTO test (data) VALUES ('hello world');
  INSERT INTO test (data) VALUES ('hello lua');
  INSERT INTO test (data) VALUES ('hello sqlite3');
  ]])
  -- print(db:errmsg())
end
database_open()

function db_test()
  print(db)
  for row in db:nrows("SELECT * FROM test") do
    print(row.id, row.data)
  end
end

--[[
The scheduler task is never preempted because lua_sethook() has not been called on it.
--]]
while 1 do
  timer_ticks = get_timer_ticks()
  local any_tasks_ready = false
  for _, task in ipairs(tasks) do
    local costatus = coroutine.status(task.co)
    if costatus == "suspended" or costatus == "normal" then
      if task.wait_until <= timer_ticks then
        any_tasks_ready = true
        local ok, errmsg = coroutine.resume(task.co)
        if not ok then
          -- print(task.name .. ": " .. errmsg)
          print(errmsg)
          -- Restart the task.
          -- taskadd(task.func, task.name)
        end
      end
    end
  end
  if not any_tasks_ready then
    -- Idle until the next interrupt.
    hlt()
  end
end


text:
-- terminus
local font = {
  [' '] =
[[

]],
  ['a'] =
[[

 ....
     .
 .....
.    .
.    .
.    .
 .....
]],
  ['b'] =
[[
.
.
.
.....
.    .
.    .
.    .
.    .
.    .
.....
]],
  ['c'] =
[[

 ....
.    .
.
.
.
.    .
 ....
]],
  ['d'] =
[[

     .
     .
 .....
.    .
.    .
.    .
.    .
.    .
 .....
]],
  ['e'] =
[[

 ....
.    .
.    .
......
.
.
 ....
]],
  ['f'] =
[[
   ...
  .
  .
......
  .
  .
  .
  .
  .
  .
]],
  ['g'] =
[[

 .....
.    .
.    .
.    .
.    .
.    .
 .....
     .
 ....
]],
  ['h'] =
[[
.
.
.
.....
.    .
.    .
.    .
.    .
.    .
.    .
]],
  ['i'] =
[[
  .
  .

 ..
  .
  .
  .
  .
  .
 ...
]],
  ['j'] =
[[
    .
    .

   ..
    .
    .
    .
    .
.   .
.   .
 ...
]],
  ['k'] =
[[
.
.
.
.    .
.   .
.  .
...
.  .
.   .
.    .
]],
  ['l'] =
[[
 ..
  .
  .
  .
  .
  .
  .
  .
  .
 ...
]],
  ['m'] =
[[

......
.  .  .
.  .  .
.  .  .
.  .  .
.  .  .
.  .  .
]],
  ['n'] =
[[

.....
.    .
.    .
.    .
.    .
.    .
.    .
]],
  ['o'] =
[[

 ....
.    .
.    .
.    .
.    .
.    .
 ....
]],
  ['p'] =
[[

.....
.    .
.    .
.    .
.    .
.....
.
.
.
]],
  ['q'] =
[[

 .....
.    .
.    .
.    .
.    .
.    .
 .....
     .
     .
]],
  ['r'] =
[[

. ....
..
.
.
.
.
.
]],
  ['s'] =
[[

 .....
.
.
 ....
     .
     .
.....
]],
  ['t'] =
[[
  .
  .
  .
.....
  .
  .
  .
  .
  .
   ...
]],
  ['u'] =
[[

.    .
.    .
.    .
.    .
.    .
.    .
 .....
]],
  ['v'] =
[[

.    .
.    .
.    .
 .  .
 .  .
  ..
  ..
]],
  ['w'] =
[[

.     .
.     .
.  .  .
.  .  .
.  .  .
.  .  .
 .....
]],
  ['x'] =
[[

.    .
.    .
 .  .
  ..
 .  .
.    .
.    .
]],
  ['y'] =
[[

.    .
.    .
.    .
.    .
.    .
.    .
 .....
     .
 ....
]],
  ['z'] =
[[

......
    .
   .
  .
 .
.
......

]],
  ['0'] =
[[
 ....
.    .
.    .
.   ..
.  . .
. .  .
..   .
.    .
.    .
 ....

]],
  ['1'] =
[[
  .
 ..
. .
  .
  .
  .
  .
  .
  .
.....

]],
  ['2'] =
[[
 ....
.    .
.    .
     .
    .
   .
  .
 .
.
......

]],
  ['3'] =
[[
 ....
.    .
.    .
     .
  ...
     .
     .
.    .
.    .
 ....

]],
  ['4'] =
[[
     .
    ..
   . .
  .  .
 .   .
.    .
......
     .
     .
     .

]],
  ['5'] =
[[
......
.
.
.
.....
     .
     .
     .
.    .
 ....

]],
  ['6'] =
[[
  ...
 .
.
.
.....
.    .
.    .
.    .
.    .
 ....

]],
  ['7'] =
[[
......
     .
     .
    .
    .
   .
   .
  .
  .
  .

]],
  ['8'] =
[[
 ....
.    .
.    .
.    .
 ....
.    .
.    .
.    .
.    .
 ....

]],
  ['9'] =
[[
 ....
.    .
.    .
.    .
.    .
 .....
     .
     .
    .
 ...

]],
  ['<'] =
[[

     .
    .
   .
  .
 .
  .
   .
    .
     .
]],
  ['>'] =
[[

 .
  .
   .
    .
     .
    .
   .
  .
 .
]],
  ['('] =
[[
  .
 .
.
.
.
.
.
.
 .
  .

]],
  [')'] =
[[
 .
  .
   .
   .
   .
   .
   .
   .
  .
 .

]],
  ['\''] =
[[

  .
  .
  .

]],
  ['"'] =
[[

.  .
.  .
.  .

]],
  ['='] =
[[

......

......

]],
  [':'] =
[[

  .
  .

  .
  .

]],
  [','] =
[[

  .
  .
 .

]],
  ['.'] =
[[

  .
  .

]],
  ['['] =
[[
...
.
.
.
.
.
.
.
.
...

]],
  [']'] =
[[
 ...
   .
   .
   .
   .
   .
   .
   .
   .
 ...

]],
  ['{'] =
[[
  ..
 .
 .
 .
.
 .
 .
 .
 .
  ..

]],
  ['}'] =
[[
..
  .
  .
  .
   .
  .
  .
  .
  .
..

]],
  ['+'] =
[[

     .
     .
   .....
     .
     .

]],
  ['-'] =
[[

......

]],
  ['_'] =
[[

......

]],
}
return font


text:
#include "util.h"

// map 0x00000000 to 0xffffffff (4GiB)
enum
{
  NUM_PML4 = 1,
  NUM_PDP  = 1,
  NUM_PD   = 4,
  NUM_PT   = 512,
};

struct PML4;
struct PDP;
struct PD;
struct PT;
struct __attribute__((aligned(4096))) PML4
{
  u64 ptr[NUM_PDP];
  struct __attribute__((aligned(4096))) PDP
  {
    u64 ptr[NUM_PD];
    struct __attribute__((aligned(4096))) PD
    {
      u64 ptr[NUM_PT];
      struct __attribute__((aligned(4096))) PT
      {
        u64 addr[512];
      } PT[NUM_PT];
    } PD[NUM_PD];
  } PDP[NUM_PDP];
} PML4[NUM_PML4] = {0};

void
setup_page_table(void)
{
  // identity map every page
  u32 addr = 0;
  for (u32 nPML4 = 0; nPML4 < arraylen(PML4); ++nPML4)
  {
    struct PML4 *PML4_ = &PML4[nPML4];
    for (u32 nPDP = 0; nPDP < arraylen(PML4_->PDP); ++nPDP)
    {
      PML4_->ptr[nPDP] = ((u32)&PML4_->PDP[nPDP] | 3);
      struct PDP *PDP_ = &PML4_->PDP[nPDP];
      for (u32 nPD = 0; nPD < arraylen(PDP_->PD); ++nPD)
      {
        PDP_->ptr[nPD] = ((u32)&PDP_->PD[nPD] | 3);
        struct PD *PD_ = &PDP_->PD[nPD];
        for (u32 nPT = 0; nPT < arraylen(PD_->PT); ++nPT)
        {
          PD_->ptr[nPT] = ((u32)&PD_->PT[nPT] | 3);
          struct PT *PT_ = &PD_->PT[nPT];
          for (u32 i = 0; i < arraylen(PT_->addr); ++i, ++addr)
          {
            PT_->addr[i] = (addr * 4096) | 3;
          }
        }
      }
    }
  }
  // Table 4-12. Use of CR3 with IA-32e Paging and CR4.PCIDE = 0
  asm volatile ("mov cr3, %0" ::"r"(PML4));
}

struct
{
  u16 baseLow;
  u16 selector;
  u8 reserved0;
  u8 flags;
  u16 baseMid;
  u32 baseHigh;
  u32 reserved1;
} __attribute__((packed)) IDT[256] = {0};

struct IDTR
{
  u16 limit;
  u64 base;
} __attribute__((packed)) IDTR = {0};

void
setIDT(u8 number, u64 base, u16 selector, u8 flags)
{
  // set base address
  IDT[number].baseLow = base & 0xFFFF;
  IDT[number].baseMid = (base >> 16) & 0xFFFF;
  IDT[number].baseHigh = (base >> 32) & 0xFFFFFFFF;

  // set selector
  IDT[number].selector = selector;
  IDT[number].flags = flags;

  IDT[number].reserved0 = 0;
  IDT[number].reserved1 = 0;
}

void
setup_IDT(void)
{
  IDTR.limit = sizeof(IDT) - 1;
  IDTR.base = (u32)IDT;
  void handle_interrupt_0(void);
  u32 addr = (u32)handle_interrupt_0;
  for (u32 i = 0; i < arraylen(IDT); ++i)
  {
    setIDT(i, addr, 0x08, 0x8E);
    addr += 32;
  }
}